【问题标题】:Checking whether a string matches any regex检查字符串是否匹配任何正则表达式
【发布时间】:2013-08-28 03:36:55
【问题描述】:

我有一个正则表达式数组和一个字符串数组。数组的大小可以任意长(例如,100 或 1000)。没有字符串匹配两个不同的正则表达式。我不确定我将如何执行它,但让我们假设它就在那里。正则表达式以pre 开头,后跟一个可选的冒号,后跟一个或多个空格,然后是一个特定的字符串,然后是一个空格,然后是一个整数。它将不区分大小写。

regexes = [/pre: my_string (\d+)/i, /pre: another (\d+)/i]
strings = ["comet", "eclipse", "sunshine", "starlight", "moonlight"]

对于每个字符串,我想检查它匹配哪个正则表达式并返回相应的匹配项。 上面的示例代码演示了我当前的方法。

strings.each {|string|
  regexes.each {|regex|
    if regex.match(string)
      p regex.match(string)
      break
    end
  }
}

似乎效率低下。有什么更有效的方法来实现这一点?

【问题讨论】:

  • 正则表达式遵循任何类型的模式还是完全通用?
  • 是的,我目前的设计中有一个特定的模式。我已经包含了它的描述。
  • 你关心哪个特定的正则表达式匹配吗?
  • 没有。只需返回第一场比赛并继续前进。

标签: ruby regex


【解决方案1】:

不要使用正则表达式数组;相反,使用搜索树。

这是一篇很棒的介绍文章:用于排序和搜索字符串的快速算法。

或者,如果您更喜欢快速而简单的解决方案,您可以使用 Ruby Regexp#union 将regexps 融合在一起以创建一个大的。这在检测 none 字符串何时匹配时可能会更有效,您可以对其进行基准测试。如果匹配,则使用匹配位置来确定匹配的正则表达式。

(感谢#union 方法的“mu is too short”的评论)

对于您描述的特定情况,所有正则表达式都以“pre”和可选冒号等开头,然后您可以执行 /pre:? +(star|moon|sun)/ 并根据匹配结果找出匹配的。

Ruby 的正则表达式是使用搜索树实现的;有一个有趣的描述可能会给你带来线索:

【讨论】:

  • 当你有Regexp.union时,你不需要任何猴子补丁。
  • @mu 你说的完全正确——这很重要,这也正是 StackOverflow 如此出色的原因。谢谢!
【解决方案2】:

我将只包含 Regexp.union() 的示例

desired = Regexp.union(/RM/, /dog/, /hat/)
x = "RM20"
y = "phat"
puts "rawr!" if y =~ desired
#=> rawr!
puts "match!" if x =~ desired
#=> match

【讨论】:

    猜你喜欢
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    • 2016-02-11
    • 1970-01-01
    • 1970-01-01
    • 2013-08-02
    相关资源
    最近更新 更多