2

是否可以创建仅当匹配不在引号内时才匹配的 pcre 正则表达式?我已经看到正则表达式使用积极的前瞻来断言'比赛后有偶数个,这在我的情况下几乎可以工作,除了奇数个引号可能出现在{and内}

示例字符串:a 'asdfasdfasdf' {' ' ' as'df'sdf}foo.bar 'asdf' { a' } asdf asdf foo.bar 'asdf' {a'} asdf'asdffoo.barasdf' 'foo.bar' asdf {'''}

当 foo.bar 不在引号中时,有什么方法可以匹配它吗?

对于我的实际用例,我已经构建了一个解析器来执行此操作,但我首先尝试使用正则表达式来解决它,并且想知道是否缺少一些技巧。

4

1 回答 1

2

如果它只是检查出现在引号之外的模式,那么解决方案很简单,您不需要使用前瞻来玩游戏。(复杂的前瞻总是产生异常缓慢的正则表达式的好方法。)知道匹配之前有偶数个引号与知道它后面有偶数个引号一样有效,前者是检查起来更容易和更快,因为它不需要在每个潜在匹配上推测性地匹配整个字符串。但是,您确实需要非贪婪的重复,否则您会找到最后一个可能的匹配而不是第一个。

这是一个简单的例子:

^(?:[^']*'[^']*')*?[^']*?foo\.bar
    |-paired 's|         |----------The pattern.
 |-shortest match-|
                   |----|
                   no quotes

但我认为你实际上也想以{}某种方式变得特别。我只是猜测,因为您似乎没有明确说明。如果括号可以嵌套,那么正则表达式就不合适了。(“Regexen 数不过来。”)

根据更新的要求(在评论中),

  1. 引号隐藏大括号
  2. 大括号隐藏引号
  3. 大括号和引号都隐藏了目标;和
  4. 大括号不嵌套

该解决方案与我上面提出的解决方案没有太大区别;我们只是添加{[^}]*}到初始模式中。这是一种可能性:

^(?:[^'{]*(?:'[^']*'|{[^}]*}))*?[^'{]*?foo\.bar

这是一个(不是很好)测试;-o 选项使 grep 显示匹配的部分,因此您可以看到每个匹配的结束位置:

$ grep -oP "^(?:[^'{]*(?:'[^']*'|{[^}]*}))*?[^'{]*?foo\.bar" <<\EOF
The target string is foo.bar and we should match the first foo.bar
'foo.bar' does not match but foo.bar does
Also, {foo.bar} doesn{'}t match, 'foo.bar' doesn{'}t match, {'foo.bar} doesn{'}t match, but foo.bar does
Note that {braces don't {nest so the end is here} and foo.bar matches}   
EOF

产生:

The target string is foo.bar
'foo.bar' does not match but foo.bar
Also, {foo.bar} doesn{'}t match, 'foo.bar' doesn{'}t match, {'foo.bar} doesn{'}t match, but foo.bar
Note that {braces don't {nest so the end is here} and foo.bar
于 2012-10-11T04:44:47.193 回答