正则表达式的前瞻/后顾注释

4

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

(?<!=#)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

1
你用的是哪种语言/工具? - anubhava
3
负向回顾后发断言的语法是 (?<!...),而不是 (?<!=...) - Casimir et Hippolyte
@CasimiretHippolyte 没有任何区别。 - bruchowski
这是因为你忘记了空格。 - Casimir et Hippolyte
1
@bruchowski:标记所用的编程语言总是很好的做法。已标记[tag:ruby],[tag:rubular],[tag:negative-lookbehind]。如有需要,请重新标记。 - smci
显示剩余4条评论
2个回答

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"

0
您可以使用此PCRE正则表达式:
/(?># *(*SKIP)(*FAIL)|(?:^|\s))test\.this\.regex\s+\"[^"]*\"/

工作演示

  • (*FAIL) 的行为类似于一个失败的否定断言,是 (?!) 的同义词。
  • (*SKIP) 定义了一个点,在该点后当子模式失败时,正则表达式引擎不允许回溯。
  • (*SKIP)(*FAIL) 一起提供了一种很好的限制的替代方法,即您不能在上面的正则表达式中拥有变长的后顾断言。

更新:不确定 Ruby 是否支持 (*SKIP)(*FAIL),因此提供此替代版本:

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

查找非空匹配组#1。

演示2


如果在#后面有一个以上的空格,这将会出错。 - bruchowski
请在您的问题中澄清这一点,这正是我问您使用哪种语言的原因所在。 - anubhava
我认为我在第一句话中已经表达了,如果你错过了,对不起;我还指出我正在使用Ruby的正则表达式实现。如果在“#”和“test.this.regex”之间有任何内容,它应该匹配,因为这意味着它是一个注释,我想忽略那个匹配。 - bruchowski
1
(#)?.*test\.this\.regex\s+\"(.*)\" 是无法帮助的,因为它将匹配两个字符串,而且在回顾后面中不能有动态长度。 - anubhava
无法在回顾后面中使用动态长度。那就是缺失的部分,谢谢,我不知道这一点。 - bruchowski
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接