使用/.*?/有什么好处

shy*_*cha 9 ruby regex cucumber

在一些Rails代码(黄瓜特征的步骤定义,javascripts,rails_admingem)中,我发现了这个正则表达式部分:

string =~ /some regexp.+rules should match "(.*?)"/i
Run Code Online (Sandbox Code Playgroud)

我对正则表达式有一些了解,我知道这些*?符号是相似的,但是星号表示zero and more,问号意味着could be present or could be not.

因此,使用问号附近的符号组使得它的存在非必需的内短语被测试.什么是......嗯......在非必需的已经组附近使用它的技巧(跳过要求是使用星号afaik)?

Mar*_*der 14

在量词(如*)之后,它?具有不同的含义并使其"不合适".因此,虽然默认值*尽可能消耗,但*?匹配尽可能少.

在您的特定情况下,这与这样的字符串相关:

some regexp rules should match "some string" or "another"
Run Code Online (Sandbox Code Playgroud)

没有问号,正则表达式匹配完整的字符串(因为.*可以"像其他任何东西一样消耗)并被some string" or "another捕获.使用问号时,匹配将尽快停止(所以之后...some string")并且仅捕获some string.

进一步阅读.

  • +1有关更多见解,请查看:[贪婪与懒惰正则表达量词的表现](http://blog.stevenlevithan.com/archives/greedy-lazy-performance)作者:Steven Levithan - (顶级正则表达式大师之一) ). (2认同)

the*_*Man 6

? 有双重意义.

/foo?/
Run Code Online (Sandbox Code Playgroud)

意味着最后一次o可以是零或一次.

/foo*?/ 
Run Code Online (Sandbox Code Playgroud)

意味着最后一次o将存在零次或多次,但选择最小数量,即它是非贪婪的.

这些可能有助于解释:

'foo'[/foo?/]   # => "foo"
'fo'[/foo?/]    # => "fo"
'fo'[/foo*?/]   # => "fo"
'foo'[/foo*?/]  # => "fo"
'fooo'[/foo*?/] # => "fo"
Run Code Online (Sandbox Code Playgroud)

non-greedy使用的?是不幸的,我认为.他们重复使用了一个我们希望有一个单一含义"零或一"的运算符,并以一种真正难以破译的方式将它扔给我们.

但是,需要是真实的:太多次我们会编写一个会出现严重错误的模式,在视线中吞噬所有内容,因为正则表达式引擎正在按照我们所说的不可预见的字符模式进行操作.正则表达式可能非常复杂和复杂,但"非贪婪"的使用?有助于驯服它.有时,使用它是草率或快速肮脏的出路,但我们没有时间重写模式来正确地做到这一点.有时它是神奇的子弹,很优雅.我认为这取决于你是否在截止日期之前编写代码来完成某项工作,或者你在事后几年进行调试并最终发现这?不是最佳解决方案.


pha*_*t0m 5

它使搜索非贪婪.这意味着,它将适应最短的匹配,而不是最长的匹配.