0

我正在尝试为 url 创建 slug。

我有以下测试字符串:

$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 被视为两个单词。

请建议如何解决这个问题。

非常感谢你。

4

2 回答 2

2

我假设,您的字符串不是 UTF-8。我认为使用变音符号/非 ASCII 字符和正则表达式,首先编码为 UTF-8 更容易,然后 - 在使用 u-修饰符(unicode)应用正则表达式之后 - 如果您需要原始编码,再次解码(根据本地) . 所以你会开始:

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

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

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

你想要所有的单词字符:

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

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

(?<=[^\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);

祝你好运!罗伯特

于 2012-11-30T10:58:02.920 回答
1

您的\b单词边界越过ö,因为它不是字母数字字符。默认情况下,PCRE 适用于 ASCII 字母。

输入字符串为 UTF-8/Latin-1。要这样处理其他非英文字母符号,请使用/uUnicode 修饰符

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

我会使用preg_replace_callbackor/e顺便说一句,而是搜索[A-Z]替换。strtr对于破折号或只是[-+]+为了折叠连续的破折号。

于 2012-11-30T05:45:05.960 回答