RegEx - 查找所有事件,但不在引号内

时间:2013-12-03 12:35:39

标签: javascript regex

我有这个文本(它是一个字符串值,而不是语言表达式):

hello = world + 'foo bar' + gizmo.hoozit + "escaped \"quotes\"";

我想找到所有单词([a-zA-Z]+),这些单词未用双引号或单引号括起来。引号可以转义(\"\')。结果应该是:

hello, world, gizmo, hoozit

我可以在JavaScript中使用正则表达式吗?

3 个答案:

答案 0 :(得分:2)

您可以使用此模式,您需要的是第二个捕获组:

编辑:稍微短一点的前瞻:

var re = /(['"])(?:[^"'\\]+|(?!\1)["']|\\{2}|\\[\s\S])*\1|([a-z]+)/ig

var mystr = 'hello = world + \'foo bar\' + gizmo.hoozit + "escaped \\"quotes\\"";';

var result = Array();
while (match = re.exec(mystr)) {
    if (match[2]) result.push(match[2]);
}

console.log(mystr);
console.log(result);

这个想法是匹配目标之前引号之间的内容。

附上内容详情:'(?:[^'\\]+|\\{2}|\\[\s\S])*'

(["'])         # literal single quote
(?:            # open a non capturing group
    [^"'\\]+   # all that is not a quote or a backslash
  |            # OR
    (?!\1)["'] # a quote but not the captured quote
  |            # OR
    \\{2}      # 2 backslashes (to compose all even numbers of backslash)*
  |            # OR
    \\[\s\S]   # an escaped character (to allow escaped single quotes)
)*             # repeat the group zero or more times
\1             # the closing single quote (backreference)

(*偶数个反斜杠不会逃避任何事情)

答案 1 :(得分:1)

你可能想要一个接一个地使用几个正则表达式方法,以简化和清晰的功能(大型正则表达式可能很快,但它们很难构建,理解和编辑):首先删除所有转义的引号,然后删除所有引用的字符串,然后运行您的搜索。

var matches = string
  .replace( /\\'|\\"/g,         '' )
  .replace( /'[^']*'|"[^']*"/g, '' )
  .match( /\w+/g );

关于正则表达式的一些注释:

  • 第二个替换中的中心构造是字符('),后面跟着集合(*)中任何字符的零个或多个([]) not(^)符合字符('
  • |表示或意味着管道之前或之后的部分可以匹配
  • '\ w'的意思是'任何单词字符',并作为'[a-zA-Z]'的简写

jsFiddle demo

答案 2 :(得分:0)

  1. 用空字符串替换每个转义的引号;
  2. 用空字符串替换每对引号和字符串:
    • 如果您使用捕获组作为开头引用(["']),那么您可以使用反向引用\1来匹配引用字符串另一端的相同样式引用;
    • 与后引用匹配意味着您需要使用非贪婪(匹配尽可能少的字符)通配符匹配.*?来获取最小可能的引用字符串。
  3. 最后,使用正则表达式[a-zA-Z]+找到匹配项。
  4. 像这样:

    var text = "hello = world + 'foo bar' + gizmo.hoozit + \"escaped \\\"quotes\\\"\";";
    
    var matches = text.replace( /\\["']/g,      '' )
                      .replace( /(["']).*?\1/g, '' )
                      .match(   /[a-zA-Z]+/g );
    
    console.log( matches );