Ответ 1
Для старых версий ruby (1.8.x) исправления - это те, которые описаны в вопросе.
Это исправлено в новых версиях ruby 1.9 +.
У меня есть случаи, когда введенные пользователем данные из html textarea или ввода иногда отправляются с \u00a0
(неразрывными пробелами) вместо пробелов при кодировании как utf-8 json.
Я считаю, что это ошибка в Firefox, так как я знаю, что пользователь не намеренно помещает нераскрывающиеся пробелы вместо пробелов.
В Ruby также есть две ошибки, одна из которых может использоваться для борьбы с другой.
По какой-либо причине \s
не соответствует \u00a0
.
Однако [^[:print:]]
, который определенно не должен совпадать) и \xC2\xA0
оба будут совпадать, но я считаю, что эти методы не являются идеальными для решения проблемы.
Существуют ли другие рекомендации по решению этой проблемы?
Для старых версий ruby (1.8.x) исправления - это те, которые описаны в вопросе.
Это исправлено в новых версиях ruby 1.9 +.
Используйте /\u00a0/
для соответствия неразрывным пробелам. Например, s.gsub(/\u00a0/, ' ')
преобразует все неразрывные пробелы в регулярные пространства.
Используйте /[[:space:]]/
для соответствия всем пробелам, включая пробелы Unicode, такие как неразрывные пробелы. Это не похоже на /\s/
, который соответствует только пробелу ASCII.
См. также: Документация Ruby Regexp
Если вы не можете использовать \s
для пробелов в Unicode, это ошибка в реализации Ruby регулярного выражения, потому что согласно UTS # 18 "Unicode Regular Exions" Приложение C о свойствах совместимости a \s
, абсолютно необходимо, чтобы соответствовать любой кодовой строке Unicode.
Не допускается использование wiggle-room, поскольку два столбца, подробно описывающие стандартную рекомендацию и совместимость с POSIX, одинаковы для случая \s
. Вы не можете документировать свой путь: вы не соблюдаете стандарт Unicode, в частности, с UTS # 18s RL1.2a, если вы не делай это.
Если вы не встретите RL1.2a, вы не отвечаете требованиям уровня 1, которые являются самой простой и элементарной функциональностью, необходимой для использования регулярных выражений в Unicode. Без этого вы в значительной степени потеряны. Вот почему существуют стандарты. Мое воспоминание о том, что Ruby также не отвечает нескольким другим требованиям уровня 1. Поэтому вы можете использовать язык программирования, который соответствует хотя бы уровню 1, если вам действительно нужно обрабатывать Unicode с регулярными выражениями.
Обратите внимание, что вы не можете использовать свойство общей категории Unicode, например \p{Zs}
, для обозначения \p{Whitespace}
. То потому что свойство Whitespace является производным свойством, а не общей категорией. В нем есть также управляющие символы, а не только разделители.
По какой-либо причине \s не соответствует \u00a0.
Я думаю, что "какая бы то ни было причина" не предполагается. Только классы символов POSIX и \p содержат символы Unicode. Аббревиатуры символьного класса не являются:
Sequence As[...] Meaning
\d [0-9] ASCII decimal digit character
\D [^0-9] Any character except a digit
\h [0-9a-fA-F] Hexadecimal digit character
\H [^0-9a-fA-F] Any character except a hex digit
\s [ \t\r\n\f] ASCII whitespace character
\S [^ \t\r\n\f] Any character except whitespace
\w [A-Za-z0-9\_] ASCII word character
\W [^A-Za-z0-9\_] Any character except a word character
Фактическое использование примеров кода IRB, которые отвечают на вопрос, с последними Rubies (май 2012)
Ruby 1.9
require 'rubygems'
require 'nokogiri'
RUBY_DESCRIPTION # => "ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]"
doc = '<html><body> </body></html>'
page = Nokogiri::HTML(doc)
s = page.inner_text
s.each_codepoint {|c| print c, ' ' } #=> 32 160 32
s.strip.each_codepoint {|c| print c, ' ' } #=> 160
s.gsub(/\s+/,'').each_codepoint {|c| print c, ' ' } #=> 160
s.gsub(/\u00A0/,'').strip.empty? #true
Ruby 1.8
require 'rubygems'
require 'nokogiri'
RUBY_DESCRIPTION # => "ruby 1.8.7 (2012-02-08 patchlevel 358) [x86_64-linux]"
doc = '<html><body> </body></html>'
page = Nokogiri::HTML(doc)
s = page.inner_text # " \302\240 "
s.gsub(/\s+/,'') # "\302\240"
s.gsub(/\302\240/,'').strip.empty? #true
Хотя это не связано с Ruby (а не напрямую на этот вопрос), ядро проблемы может заключаться в том, что Alt + Space на Mac создает неразрывное пространство.
Это может вызвать все виды странного поведения (особенно в терминале).
Для тех, кто интересуется более подробной информацией, я написал " Почему цепочки команд с трубами в Mac OS X не всегда работают" об этом тема некоторое время назад.