Конвертировать неразрывные пробелы в пробелы в Ruby - PullRequest
27 голосов
/ 07 апреля 2010

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

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

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

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

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

есть другие рекомендации для решения этой проблемы?

Ответы [ 6 ]

40 голосов
/ 01 августа 2012

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

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

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

6 голосов
/ 13 февраля 2011

Если вы не можете использовать \s для пробела Unicode, это ошибка в реализации Ruby regex, поскольку согласно UTS # 18 «Регулярные выражения Unicode» Приложение C о свойствах совместимости a \s абсолютно необходимо , чтобы соответствовать любой кодовой точке пробела Unicode.

Не допускается использование места для маневра, поскольку две колонки, в которых подробно описаны стандартная рекомендация и совместимость с POSIX, одинаковы для случая \s. Вы не можете задокументировать свой путь: вы не соответствуете стандарту Unicode, в частности, UTS # 18 RL1.2a , если вы этого не сделаете.

Если вы не соответствуете требованиям RL1.2a, вы не соответствуете требованиям уровня 1, которые являются наиболее базовой и элементарной функциональностью, необходимой для использования регулярных выражений в Unicode. Без этого вы в значительной степени потеряны. Вот почему существуют стандарты. Насколько я помню, Ruby также не удовлетворяет ряду других требований уровня 1. Поэтому вы можете использовать язык программирования, который соответствует как минимум уровню 1, если вам действительно нужно обрабатывать Unicode с регулярными выражениями.

Обратите внимание, что вы не можете использовать свойство общей категории Unicode, например \p{Zs}, для обозначения \p{Whitespace}. Это потому, что свойство Whitespace является производным свойством, а не общей категорией. В него также включены управляющие символы, а не только разделители.

2 голосов
/ 26 апреля 2012

Примеры действующих кодов IRB, которые отвечают на вопрос, с последними Рубинами (май 2012 г.)

Рубин 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

Рубин 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
2 голосов
/ 12 февраля 2011

По какой-то причине \ 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
1 голос
/ 16 октября 2014

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

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

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

1 голос
/ 26 марта 2012

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

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

...