如果它只是检查出现在引号之外的模式,那么解决方案很简单,您不需要使用前瞻来玩游戏。(复杂的前瞻总是产生异常缓慢的正则表达式的好方法。)知道匹配之前有偶数个引号与知道它后面有偶数个引号一样有效,前者是检查起来更容易和更快,因为它不需要在每个潜在匹配上推测性地匹配整个字符串。但是,您确实需要非贪婪的重复,否则您会找到最后一个可能的匹配而不是第一个。
这是一个简单的例子:
^(?:[^']*'[^']*')*?[^']*?foo\.bar
|-paired 's| |----------The pattern.
|-shortest match-|
|----|
no quotes
但我认为你实际上也想以{}
某种方式变得特别。我只是猜测,因为您似乎没有明确说明。如果括号可以嵌套,那么正则表达式就不合适了。(“Regexen 数不过来。”)
根据更新的要求(在评论中),
- 引号隐藏大括号
- 大括号隐藏引号
- 大括号和引号都隐藏了目标;和
- 大括号不嵌套
该解决方案与我上面提出的解决方案没有太大区别;我们只是添加{[^}]*}
到初始模式中。这是一种可能性:
^(?:[^'{]*(?:'[^']*'|{[^}]*}))*?[^'{]*?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