【问题标题】:Is it possible to concat two regex variables?是否可以连接两个正则表达式变量?
【发布时间】:2017-01-18 07:35:09
【问题描述】:

是否可以在 Ruby 中连接两个正则表达式变量?

r1 = /my_str/
r2 = /my_str1/
r3 = r1+r2

谁能给点建议?

【问题讨论】:

  • 串联的目标是什么?这样的正则表达式应该匹配什么?
  • 是 JavaScript 吗?当前问题的答案是否定的,但有一些方法取决于语言。 JS 见How can I concatenate regex literals in JavaScript?
  • @WiktorStribiżew 该问题已被编辑以指定 Ruby。您能否重新考虑关闭以查看欺骗是否仍然适用?

标签: ruby regex


【解决方案1】:

Regexp::union

r1 = /my_str/
r2 = /my_str1/
r3 = Regexp.union(r1, r2)

【讨论】:

  • 我不相信这是 OP 想要的解决方案。 Regexp#union 执行正则表达式“或”,即 /my_str|my_str1/。我认为 OP 想要 /my_strmy_str1/ 或 /my_str.*my_str1/.
【解决方案2】:

连接sources 并传递给Regexp.new

2.4.1 :009 > r1 = /a./
 => /a./ 
2.4.1 :010 > r2 = /b{3}/
 => /b{3}/ 
2.4.1 :011 > r3 = Regexp.new(r1.source + r2.source)
 => /a.b{3}/ 
2.4.1 :022 > "axbbb" =~ r3
 => 0 
2.4.1 :023 > "axbb" =~ r3
 => nil 

【讨论】:

    【解决方案3】:

    以下 Ruby 作品 - 但我认为它并不漂亮:

    2.5.3 :001 > r1 = /my_str1/
     => /my_str/
    2.5.3 :002 > r2 = /my_str2/
     => /my_str1/
    2.5.3 :003 > r3 = Regexp.new( "#{r1.source}|#{r2.source}" )
     => /my_str1|my_str2/
    

    当然,你甚至可以自己在 Regexp 上实现 +,就像这样(当然完全不推荐 ^^):

    class Regexp
      def +(regexp)
        self.class.new("#{source}|#{regexp.source}")
      end
    end
    

    那么你可以这样做:

    2.5.3 :004 >     class Regexp
    2.5.3 :005?>       def +(regexp)
    2.5.3 :006?>         self.class.new("#{source}|#{regexp.source}")
    2.5.3 :007?>       end
    2.5.3 :008?>     end
     => :+
    2.5.3 :009 > r1 + r2
     => /my_str1|my_str2/
    

    当然有原因,为什么没有实施。我只是假设一个或作为连接(这至少在任何情况下都应该起作用——即使在大多数情况下建议明确的开始和结束是在正则表达式中定义的)。但很可能你有一些非常不同的用例。因此,当您想以不同的方式连接时,您可能必须确保在第一个正则表达式 \Z 和第二个 \A 中必须删除...

    【讨论】:

      【解决方案4】:

      与其他答案相反,并非绝对需要致电source;在许多情况下,Regexp#to_s 也同样有效。来自文档:

      返回一个包含正则表达式及其选项的字符串(使用?(opts:source) 表示法。该字符串可以反馈到 ::new 到与原始语义相同的正则表达式。

      通常只使用字符串插值就足够了:

      r1 = /my_str1/
      # => /my_str1/ 
      r2 = /my_str2/
      # => /my_str2/ 
      r3 = Regexp.new("#{r1}|#{r2}")
      # => /(?-mix:my_str1)|(?-mix:my_str2)/ 
      

      结果比/my_str1|my_str2/ 可读性差,但匹配相同——权衡是可读性更高的源代码可读性更差。

      也就是说,如果您想对组合表达式(或其部分)应用与原始表达式不同的选项,则需要调用 source

      r1 = /[a-z]\n[0-9]/
      r2 = /[0-9]\n[a-z]/
      
      r3 = Regexp.new("(?mi-x:(#{r1.source}|#{r2.source}))")
      # => /(?mi-x:([a-z]\n[0-9]|[0-9]\n[a-z]))/
      r3.match("A\n1")
      # => #<MatchData "A\n1" 1:"A\n1">        <-- works
      
      r4 = Regexp.new("(?mi-x:(#{r1}|#{r2}))")
      # => /(?mi-x:((?-mix:[a-z]\n[0-9])|(?-mix:[0-9]\n[a-z])))/ 
      r4.match("A\n1")
      # => nil                                 <-- doesn't work b/c wrong options
      

      【讨论】:

        【解决方案5】:

        如果你有两个正则表达式,你可以像这样连接它们:

        var r1 = /my_str/;

        var r2 = /my_str1/;

        var r3 = new RegExp(r1.source + r2.source);

        【讨论】:

        • 这在 Ruby 中不起作用:*** NoMethodError Exception: undefined method `+' for /my_str1/:Regexp
        • 那不是 Ruby ;)
        猜你喜欢
        • 1970-01-01
        • 2017-06-29
        • 2019-07-13
        • 2011-02-12
        • 1970-01-01
        • 2019-01-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多