Ruby 1.9: Регулярные выражения с неизвестной входной кодировкой - PullRequest
14 голосов
/ 21 декабря 2009

Есть ли общепринятый способ работы с регулярными выражениями в 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">

Однако мне это немного неловко, и я хотел спросить, есть ли лучший способ сделать это.

Ответы [ 2 ]

9 голосов
/ 22 декабря 2009

Насколько мне известно, лучшего способа использовать нет. Тем не менее, могу ли я предложить небольшое изменение?

Вместо того, чтобы изменять кодировку ввода, почему бы не изменить кодировку регулярного выражения? Переводить одну строку регулярного выражения каждый раз, когда вы встречаете новую кодировку, гораздо меньше, чем переводить сотни или тысячи строк ввода для соответствия кодировке вашего регулярного выражения.

# 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% случаев, когда кодировка является постоянной для всего файла из сотен или тысяч строк, это приведет к значительному сокращению повторного кодирования.

0 голосов
/ 29 июня 2010

Следуйте советам на этой странице: http://gnuu.org/2009/02/02/ruby-19-common-problems-pt-1-encoding/ и добавьте

# encoding: utf-8

в начало вашего файла rb.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...