我是 ruby 新手,我正在尝试解决一个问题。
我正在解析几个要删除具有不同值的标题的文本字段。当标题始终相同时,它可以正常工作:
variable = variable.gsub(/(^Header_1:$)/, '')
但是当我提出几个论点时它不起作用:
variable = variable.gsub(/(^Header_1$)/ || /(^Header_2$)/ || /(^Header_3$)/ || /(^Header_4$)/ || /^:$/, '')
您可以使用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
只需使用适当的正则表达式:
variable.gsub(/^(Header_1|Header_2|Header_3|Header_4|:)$/, '')
如果标题始终是相同的格式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))