10

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

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

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

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

4

4 回答 4

14

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

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

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

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

进一步阅读。

于 2012-11-15T16:09:54.140 回答
6

?有双重意义。

/foo?/

意味着最后一个o可以出现零次或一次。

/foo*?/ 

表示最后一个o将出现零次或多次,但选择最小的次数,即它是非贪婪的。

这些可能有助于解释:

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

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

但是,需求是真实的:太多次我们编写的模式会大错特错,吞噬眼前的一切,因为正则表达式引擎正在使用无法预料的字符模式执行我们所说的操作。正则表达式可能非常复杂和令人费解,但“非贪婪”的使用?有助于驯服这一点。有时,使用它是一种草率或快速的方法,但我们没有时间重写模式来正确地做到这一点。有时它是灵丹妙药,而且很优雅。我认为这取决于您是否在截止日期之前并编写代码来完成某事,或者您在事实发生多年后进行调试并最终发现这?不是最佳解决方案。

于 2012-11-15T16:11:33.043 回答
5

它使搜索不贪婪。这意味着,它将满足于最短的匹配,而不是最长的匹配。

于 2012-11-15T16:09:47.870 回答
3

考虑这个字符串

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

正则表达式

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

所以,.*贪心..

正则表达式

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

所以,.*?懒惰..

于 2012-11-15T16:13:43.410 回答