Подтвердить что ты не робот

Преобразование неразрывных пробелов в пространства в Ruby

У меня есть случаи, когда введенные пользователем данные из html textarea или ввода иногда отправляются с \u00a0 (неразрывными пробелами) вместо пробелов при кодировании как utf-8 json.

Я считаю, что это ошибка в Firefox, так как я знаю, что пользователь не намеренно помещает нераскрывающиеся пробелы вместо пробелов.

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

По какой-либо причине \s не соответствует \u00a0.

Однако [^[:print:]], который определенно не должен совпадать) и \xC2\xA0 оба будут совпадать, но я считаю, что эти методы не являются идеальными для решения проблемы.

Существуют ли другие рекомендации по решению этой проблемы?

4b9b3361

Ответ 1

Для старых версий ruby ​​(1.8.x) исправления - это те, которые описаны в вопросе.

Это исправлено в новых версиях ruby ​​1.9 +.

Ответ 2

Используйте /\u00a0/ для соответствия неразрывным пробелам. Например, s.gsub(/\u00a0/, ' ') преобразует все неразрывные пробелы в регулярные пространства.

Используйте /[[:space:]]/ для соответствия всем пробелам, включая пробелы Unicode, такие как неразрывные пробелы. Это не похоже на /\s/, который соответствует только пробелу ASCII.

См. также: Документация Ruby Regexp

Ответ 3

Если вы не можете использовать \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 является производным свойством, а не общей категорией. В нем есть также управляющие символы, а не только разделители.

Ответ 4

По какой-либо причине \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

Ответ 5

Фактическое использование примеров кода 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> &nbsp; </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> &nbsp; </body></html>'
page = Nokogiri::HTML(doc)
s = page.inner_text # " \302\240 "
s.gsub(/\s+/,'') # "\302\240"
s.gsub(/\302\240/,'').strip.empty? #true

Ответ 6

Хотя это не связано с Ruby (а не напрямую на этот вопрос), ядро ​​проблемы может заключаться в том, что Alt + Space на Mac создает неразрывное пространство.

Это может вызвать все виды странного поведения (особенно в терминале).

Для тех, кто интересуется более подробной информацией, я написал " Почему цепочки команд с трубами в Mac OS X не всегда работают" об этом тема некоторое время назад.