正则表达式前瞻/后观评论

时间:2014-05-17 05:08:39

标签: ruby regex negative-lookbehind rubular

我有一个配置文件的片段,我需要能够匹配指定的字符串引用内容,但只有当它们没有被注释掉时,这是我当前的正则表达式:

(?<!=#)test\.this\.regex\s+\"(.*?)\"

我觉得这应该有效吗?我这样读了:

(?<!=#)向后看以确保其前面没有#

test\.this\.regex\s+\"(.*?)\"匹配test.this.regex "sup1"

这是配置代码段

    test.this.regex "sup1" hi |sup1| # test.this.regex "sup3" hi |sup3|
# test.this.regex "sup2" do |sup2|
    test.this.regex "sup2" do |sup2|

但我的正则表达式全部匹配4次:

Match 1
1.  sup1
Match 2
1.  sup3
Match 3
1.  sup2
Match 4
1.  sup2

2 个答案:

答案 0 :(得分:0)

您可以使用此PCRE正则表达式:

/(?># *(*SKIP)(*FAIL)|(?:^|\s))test\.this\.regex\s+\"[^"]*\"/

Working Demo

  • (*FAIL)表现得像一个失败的否定断言,是(?!)
  • 的同义词
  • (*SKIP)定义了一个点,当子模式稍后失败时,不允许正则表达式引擎回溯
  • (*SKIP)(*FAIL)一起提供了一个很好的限制替代方案,你不能在上面的正则表达式中使用可变长度的lookbehinf。

更新:不确定ruby是否支持(*SKIP)(*FAIL)所以提供此备用版本:

(?:# *test\.this\.regex\s+\"[^"]*\"|\b(test\.this\.regex\s+\"[^"]*\"))

寻找非空的匹配组#1。

Working Demo 2

答案 1 :(得分:0)

如果您的问题体现在第一句话中(而不是具体关于外观),为什么不将String#split与正则表达式一起使用而不是外观?

def doit(str)
  r = /test\.this\.regex\s+\"(.*?)\"/
  str.split('#').first[r,1]
end

doit('test.this.regex "sup1" hi |sup1| # test.this.regex "sup3" hi |sup3|')
  #=> "sup1"
doit('# test.this.regex "sup2" do |sup2|')
  #=> nil
doit('test.this.regex "sup2" do |sup2|')
  #=> "sup2"