preg_replace,character escapes&重音字符。 / u在一台服务器上运行,但不在另一台服

时间:2011-09-17 18:35:11

标签: php regex utf-8 pcre

我有以下代码:

 preg_replace('/[^\w-]/u','.','Bréánná MÓÚLÍN');

在服务器A(PHP 5.3.5)上返回:
“Bréánná.Móúlín”(应该如此)

但是,在服务器B(PHP 5.2.11)上,它返回:
“Br..n..M..l.n”(不是我想要的)

我是否正确地认为这取决于整个事情编制时是否设置了PCRE_UCP?

如果是这种情况,有没有办法覆盖这个?

如果不这样做,是否有任何方法可以轻易地用'标准'等效替换这些字符? (比如utf8_decode但更广泛)

1 个答案:

答案 0 :(得分:2)

我不确定编译期间定义的PCRE_UCP是否会影响preg_replace(),但解决问题的方法是使用多字节字符串函数mb_ereg_replace()

<?php
mb_internal_encoding("UTF-8");
mb_regex_encoding("UTF-8");

echo mb_ereg_replace('[^0-9A-Za-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-῿‌-‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�̀-ͯ‿-⁀\\-]','.','Bréánná MÓÚLÍN');

PHP 5.2结果:http://codepad.viper-7.com/UnZeyf

编辑:我原本以为多字节ereg函数支持Unicode character type escapes,但结果并非如此。相反,您需要确定您认为“字母”的字符范围。我使用XML Standard's definition of NameChar中的字符范围和以下Java程序来生成RegExp字符串(显然多字节ereg函数也不支持Unicode字符转义序列):

import java.io.*;

public class SO7456963 {
    public static void main(String[] args) throws Throwable {
        Writer w = new OutputStreamWriter(new FileOutputStream("SO7456963.txt"), "UTF-8");
        w.write("[^0-9A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u0300-\u036F\u203F-\u2040\\\\-]");
        w.close();
    }
}