Php 创建包含UTF-8的段塞
我正在尝试编写一些代码来获取UTF-8文本并创建一个包含一些UTF-8字符的slug。所以这并不是将UTF-8音译成ASCII 所以基本上我想用破折号替换任何UTF-8字符,即空白、控制字符、标点或符号。存在我应该能够使用的代码:Php 创建包含UTF-8的段塞,php,regex,utf-8,slug,Php,Regex,Utf 8,Slug,我正在尝试编写一些代码来获取UTF-8文本并创建一个包含一些UTF-8字符的slug。所以这并不是将UTF-8音译成ASCII 所以基本上我想用破折号替换任何UTF-8字符,即空白、控制字符、标点或符号。存在我应该能够使用的代码:\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
\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
(我希望这个测试中有一个-ö-in
)
它破坏了umlaut o,可能是因为在Unicode中它由两个字节c3b6
组成,其中b6
似乎被识别为标点字符(因此\p{p}
在这里匹配)。c3
仍保留在文本中。这很奇怪,因为在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
怎么办?解决方案是使用“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类别会产生奇怪的结果,而没有任何警告。有趣的问题,但是如果您为URL创建段塞,将它们转换为ASCII不是更好吗?我不这么认为,在现代浏览器中,在URL中使用UTF-8是没有问题的,这样它们的可读性会更好。即使浏览器必须在后台使用URL编码的字节(对于
ö
,使用la%C3%B6
),也是如此。然而,即使堆栈溢出本身也会转换为ASCII字符(),这可能会使键入URL更容易。好吧,堆栈溢出并不是所有智慧的终结:)如果你说这种语言,你可能就有办法编写它。在我的例子中,还有一个不带slug(ASCII)的短URL,它意味着在必要时可以键入。我声称,如今slug主要用于搜索引擎。堆栈溢出并不是所有智慧的终结——不是吗<代码>=:-O