Ruby删除与数组的任何元素匹配的子字符串

我有一个字符串说str ="this is the string " ,我有一个字符串数组说

 array =["this is" ,"second element", "third element"] 

我想处理字符串,以便匹配任何数组元素的子字符串应该被删除,其余的字符串应该返回。所以我想要以下输出。

 output: "the string " 

我怎么能在ruby中这样做。

您没有说明是否需要真正的子字符串匹配或字边界处的子字符串匹配。 有区别。 以下是如何做到尊重单词边界:

 str = "this is the string " array = ["this is" ,"second element", "third element"] pattern = /\b(?:#{ Regexp.union(array).source })\b/ # => /\b(?:this\ is|second\ element|third\ element)\b/ str[pattern] # => "this is" str.gsub(pattern, '').squeeze(' ').strip # => "the string" 

这是unionunion.source发生的事情:

 Regexp.union(array) # => /this\ is|second\ element|third\ element/ Regexp.union(array).source # => "this\\ is|second\\ element|third\\ element" 

source以一种forms返回连接数组,在创建模式时,Regex可以更容易地使用它,而不会在模式中注入空洞。 考虑这些差异以及它们在模式匹配中可以做些什么:

 /#{ Regexp.union(%w[a . b]) }/ # => /(?-mix:a|\.|b)/ /#{ Regexp.union(%w[a . b]).source }/ # => /a|\.|b/ 

第一个创建一个单独的模式,其中包含用于大小写,多行和空白空间的标记,这些标记将嵌入到外部模式中。 这可能是一个非常难以追踪和修复的错误,所以只有当你打算拥有子模式时才这样做。

另外,请注意如果您尝试使用会发生什么:

 /#{ %w[a . b].join('|') }/ # => /a|.|b/ 

生成的模式具有通配符. 嵌入其中,会破坏你的模式,使其与任何东西相匹配。 不要去那里。

如果我们不告诉正则表达式引擎遵守单词边界,那么可能会发生意外/不良/可怕的事情:

 str = "this isn't the string " array = ["this is" ,"second element", "third element"] pattern = /(?:#{ Regexp.union(array).source })/ # => /(?:this\ is|second\ element|third\ element)/ str[pattern] # => "this is" str.gsub(pattern, '').squeeze(' ').strip # => "n't the string" 

在处理包含完整单词的子串时,用词来思考是很重要的。 引擎不知道差异,所以你必须告诉它该怎么做。 这种情况经常被那些不必进行文本处理的人所忽视。

这是一种方式 –

 array =["this is" ,"second element", "third element"] str = "this is the string " str.gsub(Regexp.union(array),'') # => " the string " 

允许不区分大小写str.gsub(/#{array.join('|')}/i,'')

我看到了两种解决方案,起初我更喜欢布拉德的解决方案。 但我认为这两种方法是如此不同,以至于必须有性能差异所以我创建了下面的文件并运行它。

 require 'benchmark/ips' str = 'this is the string ' array =['this is' ,'second element', 'third element'] def by_loop(str, array) array.inject(str) { |result , substring| result.gsub substring, '' } end def by_regex(str, array) str.gsub(Regexp.union(array),'') end def by_loop_large(str, array) array = array * 100 by_loop(str, array) end def by_regex_large(str, array) array = array * 100 by_regex(str, array) end Benchmark.ips do |x| x.report("loop") { by_loop(str, array) } x.report("regex") { by_regex(str, array) } x.report("loop large") { by_loop_large(str, array) } x.report("regex large") { by_regex_large(str, array) } end 

结果:

 ------------------------------------------------- loop 16719.0 (±10.4%) i/s - 83888 in 5.073791s regex 18701.5 (±4.2%) i/s - 94554 in 5.063600s loop large 182.6 (±0.5%) i/s - 918 in 5.027865s regex large 330.9 (±0.6%) i/s - 1680 in 5.076771s 

结论:

当arrays变大时,Arup的方法效率更高。

至于Tin Man对文本中单引号的关注,我认为这非常重要,但这将是OP的责任,而不是当前的算法。 这两种方法在该字符串上产生相同的效果。