插值正则表达式中char类的过早结束

时间:2012-06-05 16:27:37

标签: ruby regex

我似乎无法解决这个问题,希望有人可以提供帮助:

Nilfacs 是从哈希中提取的字符串数组。

对于这一行:

looping_finaltext = finaltext.reject {|sentence| nilfacs.any? {|fac| sentence =~ /#{(fac)}/i}}

我收到以下错误:warning: character class has ']' without escape: /[[]]/block (2 levels) in <main>': premature end of char-class: /[[]]/i (RegexpError)

所有字符串都只是普通字(如“条件”),并且不包含需要转义的字符。

这是否表示某些意料之外的东西被作为字符串输入数组?或者这行中的语法有问题吗?

2 个答案:

答案 0 :(得分:9)

  

这是否表示某些意料之外的东西被作为字符串输入数组?

是的,就是这样。我希望你有嵌套数组,并且在那里你有一个空数组[[]]的数组,其to_s表示产生你找到的结果。

在正则表达式文字中使用插值时,源中的字符将被视为正则表达式中的字符。正如/b[/不是有效的正则表达式一样,foo="b["; bar=/#{foo}/无效。

nilfacs = [ "a[]", "b[", "c]", [[]] ]

nilfacs.each do |fac|
  begin
    p /#{fac}/
  rescue RegexpError=>e
    puts e
  end
end

#=> empty char-class: /a[]/
#=> premature end of char-class: /b[/
#=> /c]/
#=> warning: regular expression has ']' without escape: /[[]]/
#=> premature end of char-class: /[[]]/

如果您想将字符串用作文字字符,则需要使用Regexp.escape

nilfacs.each do |fac|
  p /#{Regexp.escape fac}/
end
#=> /a\[\]/
#=> /b\[/
#=> /c\]/

或者,您可能希望使用Regexp.union从数组中创建一个与其中所有文字字符串匹配的正则表达式:

rejects = %w[dog cat]
re = Regexp.new(Regexp.union(rejects).source,'i') #=> /dog|cat/i
looping_finaltext = finaltext.reject{ |sentence| sentence=~re }

答案 1 :(得分:2)

  

Nilfacs 是从哈希中提取的字符串数组。

可能不是,nilfacs几乎肯定会有一个空的AoA作为成员。在irb中尝试此操作,您会看到:

>> a = [[]]
>> /#{a}/
(irb):4: warning: character class has ']' without escape: /[[]]/
RegexpError: premature end of char-class: /[[]]/

或者您在'[[]]'中有字符nilfacs

>> a = '[[]]'
>> /#{a}/
(irb):6: warning: character class has ']' without escape: /[[]]/
RegexpError: premature end of char-class: /[[]]/

nilfacs修改为您希望的字符串数组后,您可以使用单个正则表达式而不是any?来清理代码:

re = Regexp.new(Regexp.union(nilfacs).source, Regexp::IGNORECASE)
looping_finaltext = finaltext.reject { |sentence| sentence =~ re }

正则表达式引擎可以立即检查所有模式,以避免在String#=~块内反复调用any?的开销。