искаженный символ UTF-8 при вызове rindex () для строки, содержащей символ торговой марки - PullRequest
1 голос
/ 01 июня 2011

Мне трудно понять, почему rindex () вызывает исключение для символа торговой марки в моем приложении Rails3.0.7 (ruby 1.8.7):

irb(main):007:0> "™ foo™".mb_chars.rindex(/\W/)
ActiveSupport::Multibyte::EncodingError: malformed UTF-8 character
from /opt/local/lib/ruby/gems/1.8/gems/activesupport-3.0.7/lib/active_support/multibyte/unicode.rb:72:in `u_unpack'
from /opt/local/lib/ruby/gems/1.8/gems/activesupport-3.0.7/lib/active_support/multibyte/chars.rb:167:in `rindex'
from (irb):7
irb(main):008:0> "™ foo™".mb_chars.index(/\W/)
=> 1

Но это прекрасно работает.

irb(main):009:0> "® foo®".mb_chars.rindex(/\W/)
=> 1
irb(main):010:0> "® foo®".mb_chars.index(/\W/)
=> 1

Ответы [ 2 ]

0 голосов
/ 21 июня 2011

Похоже, что это ошибка в ActiveSupport.

Вот как можно надежно копировать ее, не прибегая к вставке символов (что часто ненадежно).

Соответствующие кодовые точки:

TM symbol = 0x2122
registered symbol = 0xAE

Код:

$KCODE = 'u'
tm_char = [0x2122].pack('U')
r_char = [0xAE].pack('U')
tm_char.mb_chars.rindex(/\W/)  # error: malformed utf-8
r_char.mb_chars.rindex(/\W/)  # ok, but I expected 0 instead of nil
tm_char.mb_chars.rindex(tm_char)  # ok. but we're not using a regexp

Я подозреваю, что это связано с тем, что TM является 3-байтовым символом UTF-8, а "(R)" является 2-байтовым:

tm_char.bytes.to_a.inspect
r_char.bytes.to_a.inspect

То же самое происходит с mdash (0x2014).

Ruby 1.9.2 не имеет этой проблемы:

[0x2122].pack('U').mb_chars.rindex(/\W/)  # => 0
[0x2014].pack('U').mb_chars.rindex(/\W/)  # => 0

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

mb_string = "#{tm_char} foo#{tm_char}".mb_chars
match, rev_idx = mb_string.chars.to_a.reverse.each_with_index.detect{|e,idx| e =~ /[^a-zA-Z0-9]/ }
idx = mb_string.size - rev_idx - 1  # => 5
0 голосов
/ 02 июня 2011

Я подозреваю, что причиной может быть ваша кодировка исходного кода. Проверьте, что именно содержит эта строка во время выполнения. В этом вам может помочь http://ruby -unicode.rubyforge.org / doc /

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