我有两个数组
sentences_ary = ['This is foo', 'bob is cool']
words_ary = ['foo', 'lol', 'something']
我想检查中的任何元素是否sentences_ary
匹配中的任何单词words_ary
。
我可以检查一项工作,但是无法完成word_ary
。
#This is working
['This is foo', 'bob is cool'].any? { |s| s.match(/foo/)}
但是我无法使其与ary regex ary一起使用。我从这总是正确的:
# This is not working
['This is foo', 'bob is cool'].any? { |s| ['foo', 'lol', 'something'].any? { |w| w.match(/s/) } }
我正在用这种if
情况。
RegexpTrie对此进行了改进:
require 'regexp_trie'
sentences_ary = ['This is foo', 'This is foolish', 'bob is cool', 'foo bar', 'bar foo']
words_ary = ['foo', 'lol', 'something']
words_regex = /\b(?:#{RegexpTrie.union(words_ary, option: Regexp::IGNORECASE).source})\b/i
# => /\b(?:(?:foo|lol|something))\b/i
sentences_ary.any?{ |s| s[words_regex] } # => true
sentences_ary.find{ |s| s[words_regex] } # => "This is foo"
sentences_ary.select{ |s| s[words_regex] } # => ["This is foo", "foo bar", "bar foo"]
您必须小心如何构造正则表达式模式,否则可能会得到假阳性结果。这可能是很难追踪的错误。
sentences_ary = ['This is foo', 'This is foolish', 'bob is cool', 'foo bar', 'bar foo']
words_ary = ['foo', 'lol', 'something']
words_regex = /\b(?:#{ Regexp.union(words_ary).source })\b/ # => /\b(?:foo|lol|something)\b/
sentences_ary.any?{ |s| s[words_regex] } # => true
sentences_ary.find{ |s| s[words_regex] } # => "This is foo"
sentences_ary.select{ |s| s[words_regex] } # => ["This is foo", "foo bar", "bar foo"]
/\b(?:foo|lol|something)\b/
生成的模式足够聪明,可以查找单词边界,该单词边界将查找单词,而不仅仅是子字符串。
另外,请注意使用source
。这一点非常重要,因为缺少它会导致很难定位错误。比较这两个正则表达式:
/#{ Regexp.union(words_ary).source }/ # => /foo|lol|something/
/#{ Regexp.union(words_ary) }/ # => /(?-mix:foo|lol|something)/
注意第二个如何嵌入标记(?-mix:...)
。他们在周围的图案内部更改了封闭图案的标志。内部模式的行为可能与周围的模式有所不同,从而导致黑洞吞噬了您意想不到的结果。
甚至Regexpunion
文档也显示了这种情况,但没有提及为什么它可能很糟糕:
Regexp.union(/dogs/, /cats/i) #=> /(?-mix:dogs)|(?i-mx:cats)/
请注意,在这种情况下,两种模式都有不同的标志。在我们的团队中,我们union
经常使用,但是我总是小心翼翼地看看在同行评审中它是如何使用的。我曾经对此有所了解,很难弄清楚出什么问题了,所以我对此非常敏感。尽管union
采用了模式,如示例中所示,但我建议不要使用它们,而应使用单词数组或模式作为字符串,以避免那些讨厌的标志潜入其中。他们有时间和地点,但是了解这一点可以让我们控制它们的使用时间。
多次通读Regexp文档,因为有很多东西要学习,它将使前几次学习不堪重负。
而且,要获得额外的信用,请阅读:
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句