有没有一种接受的方式来处理
Ruby 1.9中的正则表达式,输入的编码是未知的?假设我的输入恰好是UTF-16编码:
x = "foo<p>bar</p>baz" y = x.encode('UTF-16LE') re = /<p>(.*)<\/p>/ x.match(re) => #<MatchData "<p>bar</p>" 1:"bar"> y.match(re) Encoding::CompatibilityError: incompatible encoding regexp match (US-ASCII regexp with UTF-16LE string)
我目前的方法是在内部使用UTF-8,并在必要时对输入进行重新编码(副本):
if y.methods.include?(:encode) # Ruby 1.8 compatibility if y.encoding.name != 'UTF-8' y = y.encode('UTF-8') end end y.match(/<p>(.*)<\/p>/u) => #<MatchData "<p>bar</p>" 1:"bar">
但是,这对我来说感觉有点尴尬,我想问一下是否有更好的方法.
解决方法
据我所知,没有更好的使用方法.但是,我可以建议稍作改动吗?
而不是改变输入的编码,为什么不改变正则表达式的编码?每次遇到新的编码时,翻译一个正则表达式字符串比翻译数百或数千行输入来匹配正则表达式的编码要少得多.
# Utility function to make transcoding the regex simpler. def get_regex(pattern,encoding='ASCII',options=0) Regexp.new(pattern.encode(encoding),options) end # Inside code looping through lines of input. # The variables 'regex' and 'line_encoding' should be initialized prevIoUsly,to # persist across loops. if line.methods.include?(:encoding) # Ruby 1.8 compatibility if line.encoding != last_encoding regex = get_regex('<p>(.*)<\/p>',line.encoding,16) # //u = 00010000 option bit set = 16 last_encoding = line.encoding end end line.match(regex)
在病理情况下(输入编码每行都会更改),因为您通过循环每次重新编码正则表达式,这将会很慢.但是在99.9%的编码对于数百或数千行的整个文件是不变的情况下,这将导致重新编码的大幅度减少.