我在指定&#34时遇到问题;下一个字符不应该来自这组字符"在我的正则表达式。我有
TOKENS = [":", ".", "'"]
"01:39\t" =~ /\b0\d[#{Regexp.union(TOKENS)}]\d\d^#{Regexp.union(TOKENS)}/
#=> nil
由于"\t"
不属于我的TOKENS
数组,我认为上面应该匹配,但事实并非如此。如何调整我的正则表达式,特别是这部分
^#{Regexp.union(TOKENS)}
说该字符不应该是这个数组的一部分吗?
答案 0 :(得分:0)
你需要围绕"而不是"正则表达式的一部分。
>> TOKENS = [":", ".", "'"]
>> regex = /\b0\d[#{Regexp.union(TOKENS)}]\d\d^#{Regexp.union(TOKENS)}/
>> "01:39\t" =~ regex
#=> nil
然而:
>> regex = /\b0\d[#{Regexp.union(TOKENS)}]\d\d[^#{Regexp.union(TOKENS)}]/
# Add brackets here^ and here^
>> "01:39\t" =~ regex
#=> 0
答案 1 :(得分:0)
您的/\b0\d[#{Regexp.union(TOKENS)}]\d\d^#{Regexp.union(TOKENS)}/
模式最终会显示为
/(?-mix:\b0\d[(?-mix::|\.|')]\d\d^(?-mix::|\.|'))/
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
此处,正则表达式对象是具有禁用的多行,不区分大小写和自由间距模式的修改器组。最后一个^
是行锚的开始,它就会破坏整个正则表达式,将它变成一个永远不匹配任何字符串的模式。
仅使用#{Regexp.union(TOKENS)}
字符类括号包装[...]
是不够的,您需要使用 .source
属性来摆脱{{ 1}}因为您不想否定(?-mix:...)
,m
,i
等但是,您无法使用x
因为它会在字符类中添加Regexp.union
char,所以它被视为文字字符(所以,你也会否定管道)。
您应该使用|
定义分隔符序列,以转义应在正则表达式字符类中转义的所有字符,然后放在字符类方括号之间。
TOKENS.join().gsub(/[\]\[\^\\-]/, '\\\\\\&')
请参阅Rubular demo
请注意,TOKENS = [":", ".", "'", "]"]
sep_rx = TOKENS.join().gsub(/[\]\[\^\\-]/, '\\\\\\&')
puts sep_rx
# => :.'\]
rx = /\b0\d[#{sep_rx}]\d\d[^#{sep_rx}]/
puts rx.source
# => \b0\d[:.'\]]\d\d[^:.'\]]
puts "01:39\t" =~ rx
# => 0
匹配.gsub(/[\]\[\^\\-]/, '\\\\\\&')
,]
,[
,^
和\
,并在其前面添加反斜杠。 -
中的前4个反斜杠在替换模式中定义了一个字面反斜杠,'\\\\\\&'
代表整个匹配