返回Ruby正则表达式的第一个匹配项


97

我正在寻找一种方法来在Ruby中对字符串执行正则表达式匹配,并使它在第一次匹配时短路。

我正在处理的字符串很长,从标准方式(match方法)来看,它将处理整个事情,收集每个匹配项,并返回包含所有匹配项的MatchData对象。

match = string.match(/regex/)[0].to_s

Answers:


134

你可以试试看variableName[/regular expression/]。这是来自irb的示例输出:

irb(main):003:0> names = "erik kalle johan anders erik kalle johan anders"
=> "erik kalle johan anders erik kalle johan anders"
irb(main):004:0> names[/kalle/]
=> "kalle"

这是不是在进行比赛并在幕后返回第一个结果?
纪州

7
在使用各种长度的字符串进行了一些基准测试并查看了C源代码后,发现Regex.match确实短路并且仅找到第一个匹配项。
丹尼尔·比尔兹利

3
整洁,不知道此快捷方式。
Pierre

该快捷方式上有一些文档吗?我在高处和低处搜寻我认为比较简单的任务,但发现后才解决了我的问题。谢谢!
dmourati

5
@dmourati您可以找到String#[]中记录的此功能。感谢您询问有关该文档的信息,因为在阅读该文档时,我找到了capture参数–该参数可让您返回捕获结果而不是完整匹配。
slothbear14年

68

您可以使用[]:(类似于match

"foo+account2@gmail.com"[/\+([^@]+)/, 1] # matches capture group 1, i.e. what is inside ()
# => "account2"
"foo+account2@gmail.com"[/\+([^@]+)/]    # matches capture group 0, i.e. the whole match
# => "+account2"

4
最佳答案
-akostadinov

23

如果只有比赛很重要,则可以选择

/regexp/ =~ "string"

无论哪种方式,match都应在scan搜索整个字符串时仅返回第一个匹配项。因此,如果

matchData = "string string".match(/string/)
matchData[0]    # => "string"
matchData[1]    # => nil - it's the first capture group not a second match


2

正则表达式(regex)只是有限状态机(FSM)。

FSM试图回答问题“这种状态可能吗?”

它一直尝试进行模式匹配,直到找到匹配项(成功),或者直到探索了所有路径并且没有找到匹配项(失败)为止。

成功后,问题“这种状态是否可能?” 回答为“是”。因此,不需要进一步的匹配,并且正则表达式返回。

更多关于这一点。

此外:这是一个有趣的示例,用于演示正则表达式的工作原理。在这里,使用正则表达式来检测给定数是否为素数。这个例子是用perl编写的,但是也可以用ruby编写。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.