我正在尝试向Regexp.union
命令中添加逻辑,以便可以从元素数量可能不同的数组中构建逻辑。在我的示例中,案例1正常,然后我尝试复制此字符串,但失败了,看起来Regexp.union
在内部做得还多,然后我知道样本中的regU
和RegU2
匹配了仅作为to_s
。我发现该类型为Regexp
,但是,即使它完全可行,也找不到如何转换它的方法。是否有可能实现。我还开始用case#3在循环中使用本机union
,但也遇到了麻烦。 Tx红宝石大师!
RegexData = ['alpha', 'bravo', 'charlie']
line = ' the alpha alphaaaa asdfdsaf bravo'
###1 Regex.Join with fix number of elements Works OK
regU = Regexp.union(/#{RegexData[0].chomp}/ix, /#{RegexData[1].chomp}/ix, /#{RegexData[2].chomp}/ix )
pos1 = line.enum_for(:scan, regU).map { Regexp.last_match.begin(0) }
puts '...1 regU: ' + regU.to_s.length.to_s + ' ' + regU.to_s
puts 'scan1: ' + pos1.to_s
p regU.instance_of? String ## not string
p regU.instance_of? Array ## not Array
p regU.instance_of? Class ## still not
p regU.class ## Regexp !!!!!!
puts
###2 loop with fixing regex format, no results , even regex match as string!!!!!!!!!!
regU2 = '(?-mix:'
RegexData.each_with_index {|val, index|
if val == RegexData.last then valx = '(?ix-m:' + val.chomp + '))' else valx = '(?ix-m:' + val.chomp + ')|' end
regU2 << valx
}
puts '...2 regU2: ' + regU2.to_s.length.to_s + ' ' + regU2.to_s
pos2 = line.enum_for(:scan, regU2).map { Regexp.last_match.begin(0) }
puts 'scan2: ' + pos2.to_s
if regU.to_s == regU2.to_s then puts 'Bingo to_s matched!!!! ' else puts 'xxxxxxxxxxxxxx' end
if regU == regU2 then puts 'Bingo matched!!!! ' else puts 'xxxxxxxxxxxxxx' end
答案 0 :(得分:1)
Regexp::Union
结合您的模式。如果提供了字符串,则使用该方法对它们进行转义。如果提供正则表达式,则选项将保留,并且不会转义任何字符:
regex_data = ['alpha', 'bravo', 'charlie', '1 + 1 = 2']
Regexp.union(regex_data)
#=> /alpha|bravo|charlie|1\ \+\ 1\ =\ 2/
为防止正则表达式转义,或者要添加某些选项,必须首先将字符串转换为正则表达式。这可以通过使用Array#map
来完成,将字符串提供给Regexp
构造函数以及可选的一些正则表达式选项。使用Regexp::new
方法默认情况下不会转义字符:
regexes = regex_data.map { |str| Regexp.new(str) }
Regexp.union(regexes)
#=> /(?-mix:alpha)|(?-mix:bravo)|(?-mix:charlie)|(?-mix:1 + 1 = 2)/
options = Regexp::EXTENDED | Regexp::IGNORECASE # See Regexp::new reference above
regexes = regex_data.map { |str| Regexp.new(str, options) }
Regexp.union(regexes)
#=> /(?ix-m:alpha)|(?ix-m:bravo)|(?ix-m:charlie)|(?ix-m:1 + 1 = 2)/
如果要使用带有转义的正则表达式字符的字符串,则必须首先将其传递通过Regexp::escape
并将结果传递给构造函数。
regexes = regex_data.map { |str| Regexp.new(Regexp.escape(str), options) }
Regexp.union(regexes)
#=> /(?ix-m:alpha)|(?ix-m:bravo)|(?ix-m:charlie)|(?ix-m:1\ \+\ 1\ =\ 2)/
如果必须先chomp
来考虑所有值,那么您就不必将字符串逻辑与正则表达式逻辑混在一起:
regex_data = regex_data.map(&:chomp)
# also written as: regex_data = regex_data.map { |str| str.chomp }
# or if you don't mind mutating your variable
regex_data.map!(&:chomp)