【问题标题】:Ruby gsub / regex with several arguments [duplicate]带有几个参数的Ruby gsub /正则表达式[重复]
【发布时间】:2012-11-27 02:09:02
【问题描述】:

我是 ruby​​ 新手,我正在尝试解决一个问题。

我正在解析几个要删除具有不同值的标题的文本字段。当标头始终相同时,它可以正常工作:

variable = variable.gsub(/(^Header_1:$)/, '')

但是当我输入几个参数时它不起作用:

variable = variable.gsub(/(^Header_1$)/ || /(^Header_2$)/ || /(^Header_3$)/ || /(^Header_4$)/ || /^:$/, '')

【问题讨论】:

    标签: ruby regex


    【解决方案1】:

    你可以使用Regexp.union:

    regex = Regexp.union(
      /^Header_1/,
      /^Header_2/,
      /^Header_3/,
      /^Header_4/,
      /^:$/
    )
    variable.gsub(regex, '')
    

    请注意^something$ 不适用于包含超过something 的字符串:)

    因为^ 用于匹配字符串的开头,$ 用于匹配字符串的结尾。

    所以我故意删除了$

    另外,当您只需要删除匹配的字符串时,您不需要括号。

    你也可以这样使用:

    headers = %w[Header_1 Header_2 Header_3]
    regex = Regexp.union(*headers.map{|s| /^#{s}/}, /^\:$/, /etc/)
    variable.gsub(regex, '')
    

    当然,您可以在不明确定义的情况下删除标题。

    标题后面很可能有空格?

    如果是这样,您可以这样做:

    variable = "Header_1 something else"
    puts variable.gsub(/(^Header[^\s]*)?(.*)/, '\2')
    #=>  something else
    
    variable = "Header_BLAH something else"
    puts variable.gsub(/(^Header[^\s]*)?(.*)/, '\2')
    #=>  something else
    

    【讨论】:

    • 谢谢,效果很好!
    【解决方案2】:

    只需使用适当的正则表达式:

    variable.gsub(/^(Header_1|Header_2|Header_3|Header_4|:)$/, '')
    

    【讨论】:

      【解决方案3】:

      如果标题总是与Header_n 相同的格式,其中n 是某个整数值,那么您可以大大简化您的正则表达式:

      /Header_\d+/
      

      将找到以下每一项:

      %w[Header_1 Header_2 Header_3].grep(/Header_\d+/)
      
      [
          [0] "Header_1",
          [1] "Header_2",
          [2] "Header_3"
      ]
      

      调整它以处理查找单词,而不是子字符串:

      /^Header_\d+$/
      

      或:

      /\bHeader_\d+\b/
      

      如前所述,使用Regexp.union 是一个好的开始,但盲目使用会导致模式非常缓慢或效率低下,因此请提前考虑并通过提供有用的子模式来帮助引擎:

      values = %w[foo bar]
      /Header_(?:\d+|#{ values.join('|') })/
      => /Header_(?:\d+|foo|bar)/
      

      不幸的是,Ruby 没有与 Perl 的 Regexp::Assemble 模块等效的模块,后者可以从大量单词列表中构建高度优化的模式。在 Stack Overflow 上搜索它可以做什么的例子。例如:

      use Regexp::Assemble;
      
      my @values = ('Header_1', 'Header_2', 'foo', 'bar', 'Header_3');
      my $ra = Regexp::Assemble->new;
      foreach (@values) {
          $ra->add($_);
      }
      print $ra->re, "\n";
      => (?-xism:(?:Header_[123]|bar|foo))
      

      【讨论】:

        猜你喜欢
        • 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
        相关资源
        最近更新 更多