【问题标题】:Remove all special characters from a string [duplicate]从字符串中删除所有特殊字符[重复]
【发布时间】:2012-12-16 08:51:44
【问题描述】:

我遇到了 URL 的问题,我希望能够转换可能包含任何内容的标题,并将它们剥离所有特殊字符,以便它们只有字母和数字,当然我想用连字符替换空格。

如何做到这一点?我听说过很多关于正则表达式 (regex) 的使用...

【问题讨论】:

    标签: php regex url slug


    【解决方案1】:

    这应该可以满足您的需求:

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

    用法:

    echo clean('a|"bc!@£de^&$f g');
    

    将输出:abcdef-g

    编辑:

    嘿,问一个简单的问题,如何防止多个连字符彼此相邻?并将它们替换为 1?

    function clean($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.
    }
    

    【讨论】:

    • 他专门要求用连字符替换空格...
    • 嘿,只是一个简单的问题,我怎样才能防止 2 个连字符彼此相邻?并将它们替换为 1 吗?提前致谢!
    • 嘿 umm 最后一个替换连字符的部分不起作用,当我把这个函数放到网站上时,它说它有一个空值......哦,第一个很好够了,我希望 2 或 3 个——加起来不会有太大的不同。
    • clean 函数在 preg_replace 之前执行 str_replace 是否有充分的理由,因为 reg_replace 也会处理空格?
    • 感谢它解决了我的问题,同样+1
    【解决方案2】:

    更新

    下面的解决方案有一个“SEO 更友好”的版本:

    function hyphenize($string) {
        $dict = array(
            "I'm"      => "I am",
            "thier"    => "their",
            // Add your own replacements here
        );
        return strtolower(
            preg_replace(
              array( '#[\\s-]+#', '#[^A-Za-z0-9. -]+#' ),
              array( '-', '' ),
              // the full cleanString() can be downloaded from http://www.unexpectedit.com/php/php-clean-string-of-utf8-chars-convert-to-similar-ascii-char
              cleanString(
                  str_replace( // preg_replace can be used to support more complicated replacements
                      array_keys($dict),
                      array_values($dict),
                      urldecode($string)
                  )
              )
            )
        );
    }
    
    function cleanString($text) {
        $utf8 = array(
            '/[áàâãªä]/u'   =>   'a',
            '/[ÁÀÂÃÄ]/u'    =>   'A',
            '/[ÍÌÎÏ]/u'     =>   'I',
            '/[íìîï]/u'     =>   'i',
            '/[éèêë]/u'     =>   'e',
            '/[ÉÈÊË]/u'     =>   'E',
            '/[óòôõºö]/u'   =>   'o',
            '/[ÓÒÔÕÖ]/u'    =>   'O',
            '/[úùûü]/u'     =>   'u',
            '/[ÚÙÛÜ]/u'     =>   'U',
            '/ç/'           =>   'c',
            '/Ç/'           =>   'C',
            '/ñ/'           =>   'n',
            '/Ñ/'           =>   'N',
            '/–/'           =>   '-', // UTF-8 hyphen to "normal" hyphen
            '/[’‘‹›‚]/u'    =>   ' ', // Literally a single quote
            '/[“”«»„]/u'    =>   ' ', // Double quote
            '/ /'           =>   ' ', // nonbreaking space (equiv. to 0x160)
        );
        return preg_replace(array_keys($utf8), array_values($utf8), $text);
    }
    

    上述功能的基本原理(我发现方式效率低下 - 下面的一个更好)是不应命名的服务显然运行了拼写检查和URL 上的关键字识别。

    在客户的偏执中失去了很长时间之后,我发现他们毕竟没有在想象事情——他们的 SEO 专家 [我绝对不是] 报告说,例如,将“Viaggi Economy Perù”到viaggi-economy-peru“表现得更好”比viaggi-economy-per(之前的“清理”删除了UTF8字符;Bogotà变成了bogotMedellìn 变成了 medelln 等等)。

    还有一些常见的拼写错误似乎会影响结果,对我来说唯一有意义的解释是我们的 URL 被解包,单词被挑出来,用来驱动上帝知道什么排名算法。而且这些算法显然已经输入了 UTF8 清理的字符串,因此“Perù”变成了“Peru”而不是“Per”。 “Per”不匹配,有点卡在脖子上。

    为了既保留 UTF8 字符又替换一些拼写错误,下面更快的函数变成了上面更准确的 (?) 函数。 $dict 当然需要手工定制。

    上一个答案

    一个简单的方法:

    // Remove all characters except A-Z, a-z, 0-9, dots, hyphens and spaces
    // Note that the hyphen must go last not to be confused with a range (A-Z)
    // and the dot, NOT being special (I know. My life was a lie), is NOT escaped
    
    $str = preg_replace('/[^A-Za-z0-9. -]/', '', $str);
    
    // Replace sequences of spaces with hyphen
    $str = preg_replace('/  */', '-', $str);
    
    // The above means "a space, followed by a space repeated zero or more times"
    // (should be equivalent to / +/)
    
    // You may also want to try this alternative:
    $str = preg_replace('/\\s+/', '-', $str);
    
    // where \s+ means "zero or more whitespaces" (a space is not necessarily the
    // same as a whitespace) just to be sure and include everything
    

    请注意,您可能必须首先urldecode() URL,因为 %20 和 + 实际上都是空格-我的意思是,如果您有“Never%20gonna%20give%20you%20up”,您希望它变成 Never-放弃你,而不是 Never20gonna20give20you20up 。你可能不需要它,但我想我会提到这种可能性。

    所以完成的功能连同测试用例:

    function hyphenize($string) {
        return 
        ## strtolower(
              preg_replace(
                array('#[\\s-]+#', '#[^A-Za-z0-9. -]+#'),
                array('-', ''),
            ##     cleanString(
                  urldecode($string)
            ##     )
            )
        ## )
        ;
    }
    
    print implode("\n", array_map(
        function($s) {
                return $s . ' becomes ' . hyphenize($s);
        },
        array(
        'Never%20gonna%20give%20you%20up',
        "I'm not the man I was",
        "'Légeresse', dit sa majesté",
        )));
    
    
    Never%20gonna%20give%20you%20up    becomes  never-gonna-give-you-up
    I'm not the man I was              becomes  im-not-the-man-I-was
    'Légeresse', dit sa majesté        becomes  legeresse-dit-sa-majeste
    

    为了处理 UTF-8,我使用了在网上找到的 cleanString 实现(链接已断开,但答案的开头包含所有不太深奥的 UTF8 字符的精简副本;它也很容易添加如果需要,可以添加更多字符)将 UTF8 字符转换为普通字符,从而尽可能地保留单词“look”。为了提高性能,它可以被简化并封装在函数中。

    上面的函数也实现了转换为小写 - 但这是一种品味。执行此操作的代码已被注释掉。

    【讨论】:

    • 您在第一个代码块中缺少右括号 --> $str = preg_replace('/[^A-Za-z0-9\. -]/', '', $str);
    • 请更新您的 cleanString() 源链接
    【解决方案3】:

    这里,看看这个函数:

    function seo_friendly_url($string){
        $string = str_replace(array('[\', \']'), '', $string);
        $string = preg_replace('/\[.*\]/U', '', $string);
        $string = preg_replace('/&(amp;)?#?[a-z0-9]+;/i', '-', $string);
        $string = htmlentities($string, ENT_COMPAT, 'utf-8');
        $string = preg_replace('/&([a-z])(acute|uml|circ|grave|ring|cedil|slash|tilde|caron|lig|quot|rsquo);/i', '\\1', $string );
        $string = preg_replace(array('/[^a-z0-9]/i', '/[-]+/') , '-', $string);
        return strtolower(trim($string, '-'));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-22
      • 2014-05-20
      • 2020-11-19
      • 1970-01-01
      • 2012-05-04
      • 2016-08-23
      • 1970-01-01
      相关资源
      最近更新 更多