我正在尝试编写一些代码来获取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
怎么办?
答案 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类别会产生奇怪的结果,而不会发出任何警告。