2015-07-13 4 views
1

В настоящее время я работаю над проектом, в котором пользователи могут пометить свой контент с помощью хэштегов в текстовой области. При сохранении сообщения я просматриваю содержимое, чтобы найти любые хэштеги, сохранять их и связывать их с моделью сообщения. Все работает отлично, за исключением одного изъяна, нет многобитовой поддержки, что является проблемой, поскольку этот проект будет международным и с широкой поддержкой языка.Анализ синтаксиса многобайтовых и хэштегов в PHP

Например, предположим, что у меня есть это содержание в моем посте:

$content = 'This is my testing string, look at the hashtags and see that the multibyte ones are ignored. #php #regex #my #multibyte #åäö #öl #läsa #drickaöl #tags #are #being #ignored' 

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

preg_match_all('/(#\w+)/', $content, $matches); 

Несмотря на то, это будет игнорируйте любой тег, начинающийся с знака с несколькими знаками, например å, ä или ö, или просто разбивайте каждый тег везде, где он встречается.

Люди рекомендуют метод mb_ereg(), но насколько я могу судить, это только поддержка получения логического результата, указание того, соответствует ли ваша строка шаблону.

Вы можете взглянуть на мое простое регулярное выражение here.

Пожалуйста, помогите мне понять и исправить это, чтобы я мог нормально работать с этой функцией.

Большое спасибо!

ответ

3

Вы должны использовать u флаг с регулярным выражением:

$re = '/#\w+/u'; 

См IDEONE demo

$re = '/#\w+/u'; 
$str = "This is my testing string, look at the hashtags and see that the multibyte ones are ignored. #php #regex #my #multibyte #åäö #öl #läsa #drickaöl #tags #are #being #ignored"; 
preg_match_all($re, $str, $matches); 
print_r($matches[0]); 

Возможно, вы также можете использовать \p{L} (буква категории Unicode), но это делает не представляется необходимым с \w с u Флаг Юникода уже соответствует всем буквам Юникода. Вот версия регулярных выражений с \p{L}:

$re = '/#[0-9_\p{L}]+/u'; 

См IDEONE demo

+0

Спасибо, это работает как шарм! – Jonathan

+0

Дополнительная информация: ['u' flag в PHP] (https://github.com/php/php-src/blob/master/ext/pcre/php_pcre.c#L385) включает флаги PCRE_UCP (вместе с PCRE_UTF8) в библиотеке PCRE, поэтому '\ w' соответствует символу слова Unicode. Без PCRE_UCP '\ w' соответствует обычным символам слова ASCII. http://ideone.com/I32cxm – nhahtdh

0

Вы также можете использовать PCRE Юникода propertiez: \p{L} и \p{N} этого:

preg_match_all('/(#[\p{L}\p{N}_]+)/u', $content, $matches); 

RegEx Demo