it-roy-ru.com

Удалить все специальные символы из строки

Возможный дубликат:
Очистка регулярных выражений (PHP)

У меня возникла проблема с URL-адресами. Я хочу иметь возможность преобразовывать заголовки, которые могут содержать что угодно, и в них не должно быть никаких специальных символов, чтобы они содержали только буквы и цифры, и, конечно, я хотел бы заменить пробелы дефисами.

Как это будет сделано? Я много слышал об использовании регулярных выражений (регулярных выражений) ...

184
user115422

Очень просто:

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|"[email protected]£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.
}
591
Terry Harvey

Обновление

Решение ниже имеет "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à стал bogot, Medellìn стал medelln и так далее).

Были также некоторые типичные ошибки в написании, которые, казалось, влияли на результаты, и единственное объяснение, которое имело смысл для меня, состоит в том, что наш URL распаковывался, слова выделялись и использовались, чтобы заставить Бога знать, какие алгоритмы ранжирования. И эти алгоритмы, очевидно, были снабжены очищенными UTF8 строками, так что "Perù" стал "Peru" вместо "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, being special, is escaped with \
$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 и + оба на самом деле пробелы - я имею в виду, если у вас есть "Никогда% 20gonna% 20give% 20you% 20up", вы хотите, чтобы он стал "Никогда не дам вам" , не 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 в обычные символы, сохраняя, таким образом, слово "внешний вид" в максимально возможной степени. Это может быть упрощено и заключено в функцию здесь для производительности.

Функция выше также реализует преобразование в нижний регистр - но это вкус. Код для этого был закомментирован.

93
LSerni

Здесь, проверьте эту функцию:

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, '-'));
}
34
Jeffrey