你的/\b0\d[#{Regexp.union(TOKENS)}]\d\d^#{Regexp.union(TOKENS)}/
模式最终看起来像
/(?-mix:\b0\d[(?-mix::|\.|')]\d\d^(?-mix::|\.|'))/
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
在这里,正则表达式对象是一个修饰符组,它禁用了多行、不区分大小写和自由间距模式。最后一个^
是行锚的开始,它单独破坏了整个正则表达式,将其变成了一个永远不会匹配任何字符串的模式。
#{Regexp.union(TOKENS)}
用字符类括号包装是不够的[...]
,您需要使用该.source
属性来摆脱,(?-mix:...)
因为您不想否定m
, i
,x
等。但是,您不能使用Regexp.union
,因为它会添加|
char 和 inside一个字符类,它被视为文字字符(因此,您还将否定管道)。
您应该定义分隔符序列TOKENS.join().gsub(/[\]\[\^\\-]/, '\\\\\\&')
以转义应该在正则表达式字符类中转义的所有字符,然后放在字符类方括号之间。
红宝石演示:
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
查看Rubular 演示
请注意,.gsub(/[\]\[\^\\-]/, '\\\\\\&')
匹配]
, [
,^
和\
and-
在它们前面添加一个反斜杠。前 4 个反斜杠在'\\\\\\&'
替换模式中定义了一个文字反斜杠,\\&
代表整个匹配