这是我尝试过的事情
lorem = 'Lorem ipsum dolor sit amet, co'
# => "Lorem ipsum dolor sit amet, co"
oops = ['oops']
# => ["oops"]
这是我得到的:
lorem =~ /#{oops}/
# => 1
我原本预期是零或例外。
显然它正在将字符串数组中的第一项用于oops并匹配。 '○'是Lorem ipsum中的第二个角色......'
我在Windows 7中使用Ruby 2.3.3。
答案 0 :(得分:1)
可以在正则表达式中嵌入数组,但是不能直接使用插值。如您所知,直接插值会产生character class,它将匹配元素中的所有字符以及双引号和逗号。
改为使用:
ary = ['a']
regex = Regexp.union(ary) # => /a/
/#{regex.source}/ # => /a/
ary = ['a', 'b']
regex = Regexp.union(ary) # => /a|b/
/#{regex.source}/ # => /a|b/
您可以在文档中详细了解Regexp.union
和source
。
但是等等!还有更多!
通常,您希望对该子表达式进行分组,以避免突然生成子字符串false-positive hits:
/foo#{regex.source}/ # => /fooa|b/
因为正则表达式引擎贪婪,所以会匹配fooa
或b
:
'fooa'[/foo#{regex.source}/] # => "fooa"
'foob'[/foo#{regex.source}/] # => "b"
相反,这会有所帮助:
/foo(?:#{regex.source})/ # => /foo(?:a|b)/
'fooa'[/foo(?:#{regex.source})/] # => "fooa"
'foob'[/foo(?:#{regex.source})/] # => "foob"
但还有更多!
嵌入式正则表达式维护自己的options集合,这些集合在插值时会被保留,如果您不注意,将导致难以调试的问题:
regex = Regexp.union(ary) # => /a|b/
/#{regex}/ # => /(?-mix:a|b)/
来自文档:
i
,m
和x
也可以使用(?开关)构造在子表达式级别上应用,这将启用选项< em> on ,并为括号括起的表达式禁用选项 off 。
如果外部模式使用不同的选项,例如,对于不区分大小写的匹配,则可能发生以下情况:
regex = /FOO/
'foo'[/#{regex}/i] # => nil
您认为外部表达式上的i
选项可以解决问题,但这里发生了什么:
/#{regex}/i # => /(?-mix:FOO)/i
简单的解决方法是使用上面示例中的source
方法,该方法返回表达式的文本,但不返回选项的设置:
/#{regex.source}/i # => /FOO/i
'foo'[/#{regex.source}/i] # => "foo"
使用source
并不总是正确的做法,但在您确定有意使用 的嵌入式表达式的情况下,它会有很大的帮助。不同的选项集。如果你确实达到了这一点,请务必在那时对代码进行评论,这样你的未来或继承代码的任何人都将了解正在发生的事情。否则,可能需要数天才能弄清楚发生了什么。
答案 1 :(得分:0)
我想我找到了它:
irb(main):008:0> /#{oops}/
=> /["oops"]/
正则表达式评估一个模式,该模式将查找括号中的一个字符并匹配它遇到的第一个字符,即&#39; o&#39;在Lorem ipsum的第二个位置。 。 。&#39;
我找到了吗?