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

时间:2012-11-15 16:07:52

标签: ruby regex cucumber

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

string =~ /some regexp.+rules should match "(.*?)"/i

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

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

4 个答案:

答案 0 :(得分:14)

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

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

some regexp rules should match "some string" or "another"

如果没有问号,则正则表达式与完整字符串匹配(因为.*可以像其他任何内容一样消耗")并捕获some string" or "another。使用问号后,匹配将尽快停止(因此在...some string"之后)并且仅会捕获some string

Further reading.

答案 1 :(得分:6)

?具有双重含义。

/foo?/

表示最后o可以有零次或一次。

/foo*?/ 

表示最后o将存在零次或多次,但选择最小数字,即它不贪婪。

这些可能有助于解释:

'foo'[/foo?/]   # => "foo"
'fo'[/foo?/]    # => "fo"
'fo'[/foo*?/]   # => "fo"
'foo'[/foo*?/]  # => "fo"
'fooo'[/foo*?/] # => "fo"

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

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

答案 2 :(得分:5)

进行搜索non-greedy。这意味着,它将满足最短的匹配,而不是最长的匹配。

答案 3 :(得分:3)

考虑这个字符串

"<person>1</person><person>2</person>"

正则表达式

<person>.*</person>将匹配<person>1</person><person>2</person>

所以,.* 贪婪 ..

正则表达式

<person>.*?</person>会在下一场比赛中与<person>1</person><person>2</person>匹配

因此,.*? 懒惰 ..