PHP:从字符串中删除小字,忽略单词中的德语字符

时间:2012-11-30 05:38:10

标签: php regex

我正在尝试为网址创建slugs。

我有以下测试字符串:

$kw='Test-Tes-Te-T-Schönheit-Test';

我想从此字符串中删除少于三个字符的小字。

所以,我希望输出为

$kw='test-tes-schönheit-test';

我试过这段代码:

$kw = strtolower($kw);
$kw = preg_replace("/\b[^-]{1,2}\b/", "-",  $kw);
$kw = preg_replace('/-+/', '-', $kw);
$kw = trim($kw, '-');
echo $kw;

但结果是:

test-tes-sch-nheit-test

所以,德语字符ö正从字符串中删除 和德语单词Schönheit被视为两个词。

请建议如何解决此问题。

非常感谢。

2 个答案:

答案 0 :(得分:2)

我假设你的字符串不是UTF-8。使用Umlauts / NON-ASCII字符和正则表达式,我认为,首先编码为UTF-8然后 - 使用u-modifier(unicode)应用正则表达式后 - 如果需要原始编码,再次解码(根据本地) 。所以你要从:

开始
$kw = utf8_encode(strtolower($kw));

现在您可以使用regex-unicode功能。 \ p {L}用于字母,\ p {N}用于数字。如果您将所有字母和数字视为单词字符(由您决定),那么您的边界就会相反:

[^\p{L}\p{N}]

你想要所有的单词字符:

[\p{L}\p{N}]

如果之前有一个开始^或边界,你想要这个词。你可以使用积极的lookbehind:

(?<=[^\p{L}\p{N}]|^)

替换最多2个“单词字符”,后跟边界或结尾:

[\p{L}\p{N}]{1,2}([^\p{L}\p{N}]|$)

所以你的正则表达式看起来像这样:

'/(?<=[^\p{L}\p{N}]|^)[\p{L}\p{N}]{1,2}([^\p{L}\p{N}]|$)/u'

如果您愿意,可以解码到您的本地:

echo utf8_decode($kw);
祝你好运!罗伯特

答案 1 :(得分:1)

\b字词边界超过ö,因为它不是字母数字字符。默认PCRE适用于ASCII字母。

输入字符串为UTF-8 / Latin-1。要处理其他非英文字母符号,请使用/u Unicode modifer

$kw = preg_replace("/\b[^-]{1,2}\b/u", "-",  $kw);

我会使用preg_replace_callback/e btw,而是搜索[A-Z]进行替换。并且strtr用于短划线,或仅[-+]+用于折叠连续的。