删除所有特殊字符,但不删除非拉丁字符

Remove all special chars, but not non-Latin characters

我正在使用此 PHP 功能来处理 SEO 网址。它可以很好地处理拉丁词,但我的网址是西里尔字母。此正则表达式 - /[^a-z0-9_\s-]/ 不适用于西里尔字符,请帮助我使其适用于非拉丁字符。

function seoUrl($string) {
    // Lower case everything
    $string = strtolower($string);
    // Make alphanumeric (removes all other characters)
    $string = preg_replace('/[^a-z0-9_\s-]/', '', $string);
    // Clean up multiple dashes or whitespaces
    $string = preg_replace('/[\s-]+/', ' ', $string);
    // Convert whitespaces and underscore to dash
    $string = preg_replace('/[\s_]/', '-', $string);
    return $string;
}

您需要为西里尔字母表使用 Unicode 脚本,幸运的是 PHP PCRE 使用 \p{Cyrillic} 支持它。此外,您必须设置 u (unicode) 标志来预测引擎行为。您可能还需要 i 标志来启用不区分大小写,例如 A-Z:

~[^\p{Cyrillic}a-z0-9_\s-]~ui

你不需要双重转义\s

PHP代码:

preg_replace('~[^\p{Cyrillic}a-z0-9_\s-]+~ui', '', $string);

要了解有关 Unicode 正则表达式 的更多信息,请参阅 this article

\p{L}\p{Letter} 匹配来自任何语言的任何类型的字母。

要仅匹配西里尔字符,请使用 \p{Cyrillic}

由于西里尔字符不是标准的 ASCII 字符,您必须使用 u flag/modifier,因此正则表达式将根据需要识别 Unicode 字符。

当您使用 unicode 字符时,请务必使用 mb_strtolower 而不是 strtolower

因为您将所有字符都转换为小写,所以您不必使用 i 正则表达式 flag/modifier.


以下 PHP 代码应该适合您:

function seoUrl($string) {
    // Lower case everything
    $string = mb_strtolower($string);
    // Make alphanumeric (removes all other characters)
    $string = preg_replace('/[^\p{Cyrillic}a-z0-9\s_-]+/u', '', $string);
    // Clean up multiple dashes or whitespaces
    $string = preg_replace('/[\s-]+/', ' ', $string);
    // Convert whitespaces and underscore to dash
    $string = preg_replace('/[\s_]/', '-', $string);
    return $string;
}

此外,请注意 \p{InCyrillic_Supplementary} 匹配所有 Cyrillic Supplementary characters and \p{InCyrillic} matches all non-Supplementary Cyrillic characters