【问题标题】:How to solve Warning: preg_replace(): Compilation failed: invalid UTF-8 string at offset 1如何解决警告:preg_replace(): Compilation failed: invalid UTF-8 string at offset 1
【发布时间】:2016-12-19 10:30:33
【问题描述】:

我正在尝试将以下文本重写为 url

$string="Jean-Maxime . Thäre! wouldn't %bé#äny ąśćłóżźń. OEß L'élève
&nbsp; % áàâãªä que voici est allé voir ça. Ils ont découvert où elles avaient cachées la Sainte Bible ?! <h3>\"Je suis riche\"</h3> ";

我有 3 个函数,但不知何故,它为其中一个函数返回以下错误 警告:preg_replace():编译失败:偏移 1 处的无效 UTF-8 字符串

服务器说错误在这一行

$text =preg_replace(array_keys($utf8), array_values($utf8), $text);

这是我的 3 个功能:

function normaliser($string)
{
    $string = strip_tags(mb_strtolower($string));




    return preg_replace('~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8'));
}
################################################################################
//On enleve les accents et on normalise le texte
function enlever_accents($text) {

     $utf8 = array(
    '/[áàâãªä]/u'   =>   'a',
    '/[ÁÀÂÃÄ]/u'    =>   'A',
    '/[ÍÌÎÏ]/u'     =>   'I',
    '/[íìîï]/u'     =>   'i',
    '/[éèêë]/u'     =>   'e',
    '/[ÉÈÊË]/u'     =>   'E',
    '/[óòôõºö]/u'   =>   'o',
    '/[ÓÒÔÕÖ]/u'    =>   'O',
    '/[úùûü]/u'     =>   'u',
    '/[ÚÙÛÜ]/u'     =>   'U',
    '/ç/u'           =>   'c',
    '/Ç/u'           =>   'C',
    '/ñ/u'           =>   'n',
    '/Ñ/u'           =>   'N',
    '/[\²&~#"\'{(\[|`_\^\)°+=}*;:!§?%’,;]/u'    =>   '', //J'enleve les caracteres speciaux
    '/–/u'           =>   '-', // UTF-8 hyphen to "normal" hyphen
    '/[’‘‹›‚]/u'    =>   ' ', // Literally a single quote
    '/[“”«»„]/u'    =>   ' ', // Double quote
    '/ /u'           =>   ' ', // nonbreaking space (equiv. to 0x160)
);




     $text =preg_replace(array_keys($utf8), array_values($utf8), $text);

    $text =mb_strtolower($text);


    return  normaliser($text);
}

######################################################################### 

//Fonction qui permet de reecrire les urls
function reecrire_url_titre($string) {


   $string=  enlever_accents($string);
   $string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.
   $string = preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.

   return preg_replace('/-+/', '-', $string); // Replaces multiple hyphens with single one.
}

问题主要出在这个

function enlever_accents($text) {

    $utf8 = array(
        '/[áàâãªä]/u'   =>   'a',
        '/[ÁÀÂÃÄ]/u'    =>   'A',
        '/[ÍÌÎÏ]/u'     =>   'I',
        '/[íìîï]/u'     =>   'i',
        '/[éèêë]/u'     =>   'e',
        '/[ÉÈÊË]/u'     =>   'E',
        '/[óòôõºö]/u'   =>   'o',
        '/[ÓÒÔÕÖ]/u'    =>   'O',
        '/[úùûü]/u'     =>   'u',
        '/[ÚÙÛÜ]/u'     =>   'U',
        '/ç/u'           =>   'c',
        '/Ç/u'           =>   'C',
        '/ñ/u'           =>   'n',
        '/Ñ/u'           =>   'N',
        '/[\²&~#"\'{(\[|`_\^\)°+=}*;:!§?%’,;]/u'    =>   '', //J'enleve les caracteres speciaux
        '/–/u'           =>   '-', // UTF-8 hyphen to "normal" hyphen
        '/[’‘‹›‚]/u'    =>   ' ', // Literally a single quote
        '/[“”«»„]/u'    =>   ' ', // Double quote
        '/ /u'           =>   ' ', // nonbreaking space (equiv. to 0x160)
    );


    $text = htmlentities($text, ENT_QUOTES, 'UTF-8');

     $text =preg_replace(array_keys($utf8), array_values($utf8), $text);

    $text =mb_strtolower($text);


    return  $text;
}

请如何解决警告:preg_replace(): Compilation failed: invalid UTF-8 string at offset 1 ?

【问题讨论】:

  • 在所有 preg_replace 调用中使用正则表达式中的 /u 修饰符。另外,使用mb_strtolower 而不是strtolower
  • 我刚刚对其进行了编辑并添加了以下preg_replace('/~&amp;([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i/u', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8')); 和 ``preg_replace('/-+/u', '-', $string);`` 并使用了 mb_strtolower。也许我错过了一些东西。请给我看看好吗?
  • 是的,'/ç/' =&gt; 'c',
  • 我刚刚做到了,但我仍然面临挑战。您能否复制上面编辑过的代码并告诉我答案中缺少的地方?如果它正确且有效,我会将其标记为答案,因为我仍然遇到相同的错误。谢谢

标签: php regex utf-8


【解决方案1】:

要用 PHP 替换重音字母,方法不是使用正则表达式(在你的情况下是几个),而是使用 iconv:

$yourstring = Normalizer::normalize($yourstring, Normalizer::NFC);
setlocale(LC_CTYPE, 'fr_FR');
$result = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $yourstring);

您还需要确保您的字符串开头是 UTF-8 编码的字符串。否则,在使用mb_convert之前转换它

然后处理其他字符,如果我理解你的意图,你需要做的就是只做一个替换和修剪:

$result = trim(preg_replace('~[^a-z0-9]+~i', '-', $result), '-');

(把你想保留的所有字符都放到字符类中)


function normaliser($str) {
    # convert letters with combining characters to a single unicode point
    $str = Normalizer::normalize($str, Normalizer::NFC);

    # transliterate unicode characters to ASCII
    setlocale(LC_CTYPE, 'fr_FR');
    $str = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $str);

    # convert to lowercase (since your string is now an ascii string, no need to use mb_strtolower)
    $str = strtolower($str);

    # remove html tags
    $str = strip_tags($str);

    # TODO: - deal with html entities
    #       - replace unwanted characters with an hyphen
    #       - trim leading and trailing hyphens

    return $str;
}

【讨论】:

  • 这给了我以下Jean-Maxime . Th"are! wouldn't %b'e#"any a's'cl'oz'z'n. OEss L''el`eve % 'a`a^a~aa"a que voici est all'e voir ca. Ils ont d'ecouvert o`u elles avaient cach'ees la Sainte Bible ?! 这不是那么准确且用户可读
  • @JohnMax:我怀疑您的重音字母是用两个字符而不是一个字符构建的(一个非重音字母和一个组合字符),但您可以使用 intl normalizer 之前解决这个问题。
  • 好的。请如何在 php 5.3 上使用 intl normalizer。因为这是我得到的 php.net/manual/en/normalizer.normalize.php 但我对它很陌生
  • @JohnMax:我在代码中添加了“规范化”行。有时 intl 模块未安装,请检查您的 php.ini 以了解这一点。
  • @JohnMax:安装 intl 模块。 (linux:sudo apt-get install php5-intl)(之后别忘了重启apache)
猜你喜欢
  • 1970-01-01
  • 2018-07-21
  • 1970-01-01
  • 2019-02-12
  • 2021-08-05
  • 2023-02-17
  • 2013-04-29
  • 1970-01-01
  • 2021-05-21
相关资源
最近更新 更多