如何在短语中首次出现正则表达式(使其贪婪)

时间:2012-12-06 09:26:34

标签: ruby regex regex-greedy

我正在尝试构建一个在第一次出现时停止的正则表达式。我知道我可以通过?来使其变得非贪婪。

考虑一个字符串:

"This is sample text located at first line and located at second line."

此处,我正在使用pattern1搜索pattern2

  • pattern1"text"
  • pattern2"located at"

在上面的字符串中,我想要提取"text",我的搜索模式是"located at",所以我使用以下正则表达式:

/is.*sample(.*)located at?/

如何使located at非贪婪?我正在使用http://rubular.com/来验证我的正则表达式。

1 个答案:

答案 0 :(得分:2)

你的正则表达式不正确。

如果你想在第一个“位于”之前出现一个“单词”,你可以使用:

"This is sample text located at first line and located at second line."[/(\S+)\s+located at/, 1]
=> "text"

我使用\S将“单词”定义为非空白字符,因此标​​点符号和数字将包含在字母字符中。如果您需要\w,可以使用其他类,例如[A-Za-z0-9_]。否则请使用[a-z],如:

"This is sample text located at first line and located at second line."[/([a-z]+)\s+located at/i, 1]
=> "text"

如果您想在“样本”和第一个“位于”之间出现任何文本,您可以使用:

"This is sample text located at first line and located at second line."[/sample\s+(.+?)\s+located at/, 1]
=> "text"

在您的模式/test.*sample(.*)located at?/中,您使用多个.*,这意味着零或更多的任何事情(但是,根据上下文不是真的,但这比我们需要的更深马上)。那个“更多”是你正在碰撞的部分,因为它是贪婪的。并且,因为你使用它两次,它是双重贪心。您可以通过添加?来使用“非贪婪”变体,但它仍然无法正常工作,因为您正在为正则表达式引擎提供过多的绳索。我的模式收紧了所有,减少了在前两个中使用?修饰符的需要。

我的第三个例子需要它,因为.+同样是贪婪的,需要进行审核。

最后,您的模式中的at?未应用?来修改.*,它会对前面的t采取行动,导致引擎处于“零”状态或者'必须'找到“,这不是你想要的,因为它会匹配”a“或”at“。