0

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

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

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

但是当我提出几个论点时它不起作用:

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

3 回答 3

3

您可以使用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
于 2012-11-26T16:48:47.430 回答
2

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

variable.gsub(/^(Header_1|Header_2|Header_3|Header_4|:)$/, '')
于 2012-11-26T16:48:42.470 回答
0

如果标题始终是相同的格式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))
于 2012-11-26T17:54:08.093 回答