【问题标题】:How do I specify in Ruby that I want to match a character provided that a sequence following that character does not match a pattern?如果该字符后面的序列与模式不匹配,我如何在 Ruby 中指定我想要匹配的字符?
【发布时间】:2018-05-15 20:18:54
【问题描述】:

我正在使用 Ruby on Rails 5.1。在 Ruby 中,如果第一个字符匹配某个字符但后面的序列与模式不匹配,我该怎么说我想匹配一个字符串?也就是说,我想匹配一个数字,前提是 taht 后面的序列不是我后面跟着其他两个数字的数组中的字符。这是我的字符数组...

2.4.0 :010 > 代币 => [":", ".", "'"]

所以这个字符串不匹配

3:00

因为 ":00" 匹配我的数组中的字符模式,后跟两个数字。但是这个字符串

3400

会匹配。该字符串也将匹配

3:0

这会匹配

3

因为上面没有任何内容。如何在 Ruby 中编写适当的正则表达式?

【问题讨论】:

    标签: ruby regex pattern-matching


    【解决方案1】:
    string =~ /\A\d+(?!:\d{2})/
    

    这个正则表达式的意思是:

    • \A 将匹配锚定到字符串的开始
    • \d+ 表示“一位或多位数字”。
    • (?!...) 是一个负前瞻。它检查括号中包含的模式是否匹配。从当前位置向前看。
    • :\d{2} 表示 : 后跟两位数字。

    【讨论】:

      【解决方案2】:

      应考虑分别测试第一个字符和其余字符。

      def match_it?(str, first_char_regex, no_match_regex)
        str[0].match?(first_char_regex) && !str[1..-1].match?(no_match_regex)
      end
      
      match_it?("0:00", /0/, /\A[:. ]cat\z/)           #=> true
      match_it?("0:00", /\d/, /\A[:. ]\d+\z/)          #=> false
      match_it?("0:00", /[[:alpha:]]/, /\A[:. ]\d+\z/) #=> false
      

      我相信这读起来很好,与使用单个正则表达式的方法相比,它简化了测试。

      【讨论】:

      • 问题有点模棱两可:“我想匹配一个数字,后面不跟...”。您的抽象假设“一个数字”只有 一位数字,而单正则表达式解决方案更通用。
      • 例如,您的方法不能很好地确保像 10:00 这样的字符串 匹配。这是可能的,但 IMO 比开始执行单个正则表达式更令人困惑! match_it?("10:00", /\d/, /\A\d*:\d+\z/)
      • @Tom,你可能是对的。我对这个问题进行了字面解释,但在重新阅读时,我发现它在内部不一致。 “有点暧昧”?我的主永远那么善良。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多