2010-11-29 2 views
10

Мне нужно разбить строку и извлечь слова, разделенные пробельными символами. Источник может быть на английском или японском. Английские символы пробелов включают в себя вкладку и пробел, а японский текст также использует их. (IIRC, все широко используемые японские наборы символов являются надмножествами US-ASCII.)Что все японские символы пробелов?

Таким образом, набор символов, которые мне нужно использовать для разделения строки, включает в себя обычное пространство ASCII и вкладку.

Но на японском языке существует еще один космический символ, обычно называемый пространством полной ширины. Согласно моей утилите просмотра персонажей Mac, это U + 3000 «IDEOGRAPHIC SPACE». Это (обычно), что приводит к тому, что пользователь нажимает пробел при вводе в японский режим ввода.

Есть ли другие символы, которые мне нужно учитывать?

Я обрабатываю текстовые данные, представленные пользователями, которым было сказано «отдельные записи с пробелами». Тем не менее, пользователи используют самые разные компьютерные и мобильные операционные системы для отправки этих текстов. Мы уже видели, что пользователи могут не знать, находятся ли они в японском или английском режиме ввода при вводе этих данных.

Кроме того, поведение ключа пространства различается по платформам и приложениям даже в японском режиме (например, Windows 7 вставляет идеографическое пространство, но iOS будет вставлять пространство ASCII).

Так что я хочу в основном «набор всех символов, которые визуально выглядят как пространство и могут быть сгенерированы, когда пользователь нажимает клавишу пробела или клавишу табуляции, поскольку многие пользователи не знают разницы между пространством и вкладка на японском и/или английском языках ».

Есть ли авторитетный ответ на такой вопрос?

+1

Не следует ли использовать какой-либо язык программирования с надлежащей поддержкой Unicode, чтобы вы разделили строку (используя регулярное выражение) на пробелы? Например - `/ \ s /` соответствует символам пробела в JavaScript (эквивалентно `[\ f \ n \ r \ t \ v \ u00A0 \ u2028 \ u2029]`). – 2010-11-29 05:08:32

+3

Мэтт: Регулярное выражение, которое вы цитируете, уже отсутствует `\ u3000`, и ОП задается вопросом, что еще может быть отсутствовать. Список пространств разделителей Unicode имеет 18 записей: http://www.fileformat.info/info/unicode/category/Zs/list.htm – Gabe 2010-11-29 05:28:42

ответ

4

Вам нужна вкладка ASCII, пробел и неразрывное пространство (U + 00A0) и пространство полной ширины, которое вы правильно идентифицировали как U + 3000. Возможно, вам понадобятся символы новой строки и вертикального пробела. Если ваш ввод находится в юникоде (не Shift-JIS и т. Д.), Тогда это все, что вам нужно. Существуют и другие (контрольные) символы, такие как \ 0 NULL, которые иногда используются как разделители информации, но они не будут отображаться как пространство в восточноазиатском тексте, то есть они не будут отображаться как пробелы.

Редактировать: Мэтт Болл имеет хороший момент в своем комментарии, но, как показывает его пример, многие реализации регулярных выражений не справляются с полной шириной восточноазиатской пунктуации. В связи с этим стоит упомянуть, что Python's string.whitespace также не будет вырезать горчицу.

3

Я только что нашел ваше сообщение. Это отличное объяснение нормализации символов Unicode.

http://en.wikipedia.org/wiki/Unicode_equivalence

Я обнаружил, что многие языки программирования, как Python, есть модули, которые могут выполнять эти правила нормализации стандартов Unicode. Для моих целей я нашел, что следующий код python работает очень хорошо. Он преобразует все unicode-варианты пробелов в диапазон ascii. После нормализации, регулярное выражение команда может преобразовать все белое пространство ASCii \ x32:

import unicodedata 
# import re 

ucode = u'大変、 よろしくお願い申し上げます。' 

normalized = unicodedata.normalize('NFKC', ucode) 

# old code 
# utf8text = re.sub('\s+', ' ', normalized).encode('utf-8') 

# new code 
utf8text = ' '.join(normalized.encode('utf-8').split()) 

С первого письма я узнал, регулярное выражение в Python (повторно) модуль неправильно itentifies эти пробельные символы и может привести к аварии, если встречаются. Получается более быстрый и надежный метод использования функции .split().

Смежные вопросы