ruby - 正则表达式只返回一个匹配项

标签 ruby regex

我有一组关键词。任何关键字都可以包含空格符号 ['one', 'one two']。我从这些关键词生成一个正则表达式,如 /\b(?i:one|one\two|three)\b/。完整示例如下:

keywords = ['one', 'one two', 'three']
re = /\b(?i:#{ Regexp.union(keywords).source })\b/
text = 'Some word one and one two other word'
text.downcase.scan(re)

这段代码的结果是

=> ["one", "one"]

如何找到第二个关键字 one two 的匹配项并得到这样的结果?

=> ["one", "one two"]

最佳答案

正则表达式渴望匹配。一旦找到匹配项,他们就不会尝试找到另一个可能更长的匹配项(有一个重要的异常(exception))。

/\b(?i:one|one\two|three)\b/ 永远不会匹配 one two 因为它总是匹配 一个第一。你需要 /\b(?i:one two|one|three)\b/ 所以它首先尝试 one two 。可能最简单的自动化方法是首先按最长的关键字排序。

keywords = ['one', 'one two', 'three']
re = Regexp.union(keywords.sort { |a,b| b.length <=> a.length }).source
re = /\b#{re}\b/i;
text = 'Some word one and one two other word'
puts text.scan(re)

请注意,我将整个正则表达式设置为不区分大小写,比 (?:...) 更易于阅读,并且将字符串小写是多余的。


异常(exception)是repetition+* 和 friend 。默认情况下,它们是贪婪的.+ 将匹配尽可能多的字符。那是贪婪的。你可以让它变得懒惰,用 ? 来匹配它看到的第一件事。 .+? 将匹配单个字符。

"A foot of fools".match(/(.*foo)/);  # matches "A foot of foo"
"A foot of fools".match(/(.*?foo)/);  # matches "A foo"

关于ruby - 正则表达式只返回一个匹配项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41943461/

相关文章:

ruby-on-rails - 如何更改 Rails 3 路由中的默认参数名称?

java - 正则表达式: Replace a word conditionally

python - 如何创建一个返回嵌入记录中的值的函数?

java - 我可以使用预配置的机器镜像,并在具有 diff.RAM+CPU 的机器上预安装了 Ruby/Java

ruby-on-rails - 没有路由匹配 [GET]/users

ruby-on-rails - rails : Make Route Helper Methods Available to PORO

ruby - 我怎样才能只写一次 "Text"并同时检查 path_info 是否包含 'A' ?

xml - 替换 XML 元素的值? Sed正则表达式?

regex - Linux - 在路径中的每个斜杠后查找与正则表达式匹配的结果

php - 只用正则表达式匹配罗马数字