使用JS匹配简单的正则表达式模式(键:值)

时间:2013-07-31 19:52:10

标签: javascript regex capture key-value

我有一个简单的场景,我希望匹配以下内容并捕获值:

stuff_in_string,
env: 'local', // want to match this and capture the content in quotes
more_stuff_in_string

我从来没有写过正则表达式,所以请原谅我的尝试,我很清楚这是完全错误的。

这就是我想说的:

  • 匹配“env:”
  • 后面没有或多个空格
  • 后跟单引号或双引号
  • 全部捕捉......
  • 下一个单引号或双引号

/env:*?\s+('|")+(.*?)+('|")/g

由于

PS这是一个#failed小提琴:http://jsfiddle.net/DfHge/

注意:这是我最终使用的正则表达式(不是下面的答案,因为它对我的需求来说太过分了):/env:\s+(?:"|')(\w+)(?:"|')/

3 个答案:

答案 0 :(得分:2)

env *('|").*?\1正是您要找的

*表示无或更多

('|")匹配单引号或双引号,并将其保存到一组进行反向引用

.*?是一个不情愿的贪婪比赛

\1将引用第一组,即单引号或双引号

答案 1 :(得分:2)

您可以使用:

/\benv: (["'])([^"']*)\1/g

其中\1是对第一个捕获组的反向引用,因此您的内容位于第二个捕获组中。这是简单案例的简单方法。

现在,其他案例如:

env: "abc\"def"
env: "abc\\"
env: "abc\\\def"
env: "abc'def"

您必须使用更具约束力的模式:

首先:避免引用不同的问题:

/\benv: (["'])((?:[^"']+|(?!\1)["'])*)\1/g

我将所有可能的内容放在一个我可以随意重复的非捕获组中,并使用否定前瞻(?!\1)来检查允许的引用是否与捕获的引用不同。

第二:反斜杠问题:

如果报价被转义,则不能是收盘报价!因此,您必须检查报价是否已转义,并允许字符串中的转义引号。

我从允许的内容中删除了反斜杠:

/\benv: (["'])((?:[^"'\\]+|(?!\1)["'])*)\1/g

我允许转义字符:

/\benv: (["'])((?:[^"'\\]+|(?!\1)["']|\\[\s\S])*)\1/g

要在引用部分之前允许可变数量的空格,您可以将:替换为:\s*

/\benv:\s*(["'])((?:[^"'\\]+|(?!\1)["']|\\[\s\S])*)\1/g

你现在有一个工作模式。

第三:模式优化

一个简单的替换:

使用捕获组和反向引用可以引诱处理不同类型的引号,因为它允许以简洁的方式编写模式。但是,这种方式需要创建一个捕获组并测试此部分(?!\1) [“']`中的前瞻,因此效率不高。编写简单的替换会增加模式长度并需要使用两个捕获两个案例的小组但效率更高:

/\benv:\s*(?:"((?:[^"\\]+|\\[\s\S])*)"|'((?:[^'\\]+|\\[\s\S])*)')/g

(注意:如果你决定这样做,你必须检查两个捕获组中的哪一个被定义。)

展开循环:

为匹配引号内的内容,我们使用(?:[^"\\]+|\\[\s\S])* (此处为双引号),但可以改进以减少所需的步骤量。为此,我们将展开包含避免交替的循环:

[^"\\]*(?:\\[\s\S][^"\\]*)*

最后整个模式可以写成:

/\benv:\s*(?:"([^"\\]*(?:\\[\s\S][^"\\]*)*)"|'([^'\\]*(?:\\[\s\S][^'\\]*)*)')/g

答案 2 :(得分:1)

regex=/env: ?['"]([^'"])+['"]/
answer=str.match(regex)[1]

更好:

regex=/env: ?(['"])([^\1]*)\1/