Ruby 1.9: Регулярные выражения с неизвестным входным кодированием

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

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

14
задан DataWraith 21 December 2009 в 19:37
поделиться

2 ответа

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

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

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

.
9
ответ дан 1 December 2019 в 15:21
поделиться

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

# encoding: utf-8

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

0
ответ дан 1 December 2019 в 15:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: