JS导入语句的正则表达式匹配

7
我正在使用node读取文件的内容。我需要匹配特定的导入语句,其中该文件看起来像这样。
我只需要匹配包含“foo-bar”包的行或多行。我对获取该包中的导入很感兴趣。
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
import { connect } from 'react-redux'
import { foo, bar, fooBar } from 'foo-bar'
import { anotherThing } from 'another-module'

它也可以像这样跨越多行。
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom'
import { connect } from 'react-redux'
import { 
    foo, 
    bar, 
    fooBar 
} from 'foo-bar'
import { anotherThing } from 'another-module'

我尝试使用这个正则表达式,但它匹配了从“import”到包含foo-bar的行的末尾的所有行。我只想匹配从import到以“foo-bar”结尾的行的末尾或行。在JavaScript正则表达式中是否可能实现这一点?此外,如果有比使用正则表达式更好的方法,我也可以考虑其他选项。
import([\s\S]*?)(?=foo-bar').*

单行示例: https://regex101.com/r/U1j2G6/1 多行示例: https://regex101.com/r/kcA7gd/1

1
在这里尝试使用 import[^']+(?= from 'foo-bar') 这里这里 - Paolo
我没有花哨的链接,但你可以尝试这个import(?:(?!import).)*'foo-bar' - Adam H
开始在模式描述中更加精确。例如:https://regex101.com/r/mqyudC/1 - Casimir et Hippolyte
3个回答

6

更新: 正如@jhm2k在下面的答案中指出的那样,以下regEx存在多个问题。阅读此内容的人应该查看他的答案或我在github上重新制作的版本


我开发了这个正则表达式,匹配任何可以作为有效导入语句的内容:

import([ \n\t]*(?:[^ \n\t\{\}]+[ \n\t]*,?)?(?:[ \n\t]*\{(?:[ \n\t]*[^ \n\t"'\{\}]+[ \n\t]*,?)+\})?[ \n\t]*)from[ \n\t]*(['"])([^'"\n]+)(?:['"])

它具有以下捕获组:

  • $1 导入变量
  • $2 用于导入的引号
  • $3 导入路径

对于您的情况,您可以测试 $3。

使用时要小心,因为它还会匹配字符串内的出现。此外,我不会盲目使用它,可能存在错误并且速度较慢。

我使用以下文件进行测试:

import someClass from "src"
import someClass from"src"
import
someClass
from
"src"
import someClass
from       "src"

import {class1,class2} from "src"
import {
    class1,
    class2
            } from"src"

    import {
        class1

                } from "src"

import defaultClass   ,

{
    class1
}

  from "src"

import defaultClass,

{
    class1
}from "src"

import someClass from "src";import someClass from "src"


"I disagree about your import practices from 'src/who knows where'"
`import someClass from "src"
import someClass from"src"
import
someClass
from
"src"
import someClass
from       "src"

import {class1, class2} from "src"
import {
    class1,
    class2
            } from"src"

    import {
        class1

                } from "src"

import defaultClass   ,

{
    class1
}

  from "src"

import defaultClass,

{
    class1
}from "src"
`

在regex101.com中会出现“灾难性回溯错误”。 - Sarvesh Bhatnagar
1
除非您正在查看未编辑的版本,否则它应该可以正常工作。https://regex101.com/r/0s3fBy/1(第一次发布时,我错过了必须转义某些字符才能正确查看的事实。) - Antón Kryukov Chinaev
这个很棒!谢谢!另外,感谢你制作了我见过的最疯狂的正则表达式之一。lol - BaronVonKaneHoffen

3
我通过使用负捕获组来解决你遇到的问题,它将匹配尽可能多的字符,直到 }
以下是正则表达式。
import {[^}]*}.*'foo-bar'

Try it online!


1

这里是@Antón Kryukov Chinaev答案的更新和改进版本:

import(?:(?:(?:[ \n\t]+([^ *\n\t\{\},]+)[ \n\t]*(?:,|[ \n\t]+))?([ \n\t]*\{(?:[ \n\t]*[^ \n\t"'\{\}]+[ \n\t]*,?)+\})?[ \n\t]*)|[ \n\t]*\*[ \n\t]*as[ \n\t]+([^ \n\t\{\}]+)[ \n\t]+)from[ \n\t]*(?:['"])([^'"\n]+)(['"])

支持 import * as x from 'y' 的新版本发布了,之前的版本不支持该功能。此外,改进了捕获组并加强了正则表达式以防止误匹配,例如 importx from'y'

新的捕获组包括:

  • $1 = 默认导入名称(可以不存在)
  • $2 = 解构导出(可以不存在)
  • $3 = 通配符导入名称(可以不存在)
  • $4 = 模块标识符
  • $5 = 引号使用情况('"

Regex101 Playground with tests used


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接