2014-01-21 1 views
1

Я пытаюсь написать некоторый код, чтобы взять текст UTF-8 и создать пул, содержащий некоторые символы UTF-8. Так что речь идет не о транслитерации UTF-8 в ASCII.Создание пула с UTF-8 в нем

Так что я хочу заменить любой символ UTF-8, который является пробелом, символом управления, пунктуацией или символом с тире. Существует Unicode categories, что я должен уметь использовать: \p{Z}, \p{C}, \p{P}, или \p{S}, соответственно.

Так что я мог бы сделать что-то же просто, как это:

preg_replace("#(\p{P}|\p{C}|\p{S}|\p{Z})+#", "-", "This. test? has an ö in it"); 

, но это приводит к следующим образом:

This-test-has-an-√-in-it 

(и я хочу This-test-has-an-ö-in-it)

Это палачи umlaut o, возможно, потому что в Юникоде он состоит из двух байтов c3b6, из которых b6 кажется признанным символом пунктуации (так что здесь находятся \p{P}). c3 остается в тексте. Это странно, потому что AFAIK в байтах b6 не существует в UTF-8.

Я также попробовал то же самое в Perl для того, чтобы убедиться, что это не проблема, PHP, но код

$s = 'This. test? has an ö in it'; 
$s =~ s/(\p{P}|\p{C}|\p{S}|\p{Z})+/-/g; 

также производит:

This-test-has-an-√-in-it 

(который, вероятно, имеет смысл как PHP PCRE - это регулярные выражения, совместимые с Perl)

Пока я это делаю в Python

import regex as re 
text=u"This. test? has an ö in it"; 
print re.sub(ur"(\p{P}|\p{C}|\p{S}|\p{Z})+", "-", text) 

производит мой желаемый

This-test-has-an-ö-in-it 

Что делать?

+0

Интересный вопрос, но если вы создаете пули для URL-адресов, не лучше ли их конвертировать в ASCII? – halfer

+0

Я так не думаю, что с современными браузерами не проблема UTF-8 в URL-адресах, поэтому они будут более читабельными. Даже если браузеру приходится обращаться к urlencoded байтам (a la '% C3% B6' для' ö') в фоновом режиме. – akirk

+0

Это правда, да. Однако даже Stack Overflow сам транслитерирует символы ASCII (см. Здесь) (http://stackoverflow.com/search?q=%C3%B6)), что, возможно, упрощает ввод URL-адресов. – halfer

ответ

2

Решение было использовать "Unicode модификатор" u:

preg_replace("#(\p{P}|\p{C}|\p{S}|\p{Z})+#u", "-", "This. test? has an ö in it"); 

правильно производит

This-test-has-an-ö-in-it 

Итак: с использованием Unicode Категории без модификатора Unicode дает странные результаты без каких-либо предупреждений.

+2

oh, справа. Спасибо за напоминание! – akirk