在其中创建一个包含UTF-8的slug

时间:2014-01-21 09:21:09

标签: php regex utf-8 slug

我正在尝试编写一些代码来获取UTF-8文本并创建一个包含一些UTF-8字符的slug。所以这不是将UTF-8音译为ASCII。

所以基本上我想要替换任何空格,控制字符,标点符号或带破折号的符号的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 进行屠杀,可能是因为在Unicode中它由两个字节c3b6组成,b6似乎被识别为标点字符(所以\p{P}匹配此处)。 c3保留在文本中。这很奇怪,因为AFAIK在UTF-8中不存在单个字节b6

我也在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

怎么办?

1 个答案:

答案 0 :(得分: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类别会产生奇怪的结果,而不会发出任何警告。