Usuń wszystkie znaki specjalne z łańcucha [duplikat]

to pytanie ma już odpowiedzi tutaj : Konwertuj ciąg znaków na slug tylko z ogranicznikami z pojedynczymi myślnikami (9 odpowiedzi) Zamknięte w zeszłym roku .

Mam do czynienia z problemem z adresami URL, chcę być w stanie konwertować tytuły, które mogą zawierać cokolwiek i pozbawić je wszystkich znaków specjalnych, aby miały tylko litery i cyfry i oczywiście chciałbym zastąpić spacje myślnikami.

Jak to zrobić? Wiele słyszałem o używaniu wyrażeń regularnych (regex)...

Author: Community, 2013-01-01

3 answers

To powinno zrobić to, czego szukasz:

function clean($string) {
   $string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.

   return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
}

użycie:

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

Wyświetli: abcdef-g

Edit:

Hej, tylko szybkie Pytanie, Jak mogę zapobiec wielokrotnym myślnikom obok siebie? i zastąpić je tylko 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.
}
 703
Author: Terry Harvey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-02 16:33:12

Update

Poniższe rozwiązanie ma wersję "przyjazną 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);
}

Uzasadnienie dla powyższych funkcji (które uważam sposób nieefektywny - ta poniżej jest lepsza) jest to, że usługa, która nie powinna być nazwana najwyraźniej sprawdzała pisownię i rozpoznawała słowa kluczowe na adresach URL.

Po dłuższym czasie spędzonym na paranoiach klienta, dowiedziałem się, że to oni nie w końcu wyobrażają sobie rzeczy -- ich eksperci SEO [na pewno nie jeden z nich poinformował, że np. konwersja "Viaggi" na viaggi-economy-peru "zachowywała się lepiej" niż viaggi-economy-per (poprzednie "czyszczenie" usunęło znaki UTF8; Bogota stała się Bogota, Medellìn stał się medelln i tak dalej).

Były też pewne częste błędy pisowni, które wydawały się wpływać na wyniki, a jedyne wyjaśnienie, które miało dla mnie sens, to to, że nasz adres URL był rozpakowywany, słowa wyróżniane i używane do kierowania Bóg wie, jaki ranking algorytmy. I te algorytmy najwyraźniej były zasilane strunami oczyszczonymi UTF8, tak że " Perù "stało się" Peru "zamiast"Per". "Per" nie pasował i jakby dostał w szyję.

Aby zarówno zachować znaki UTF8, jak i zastąpić niektóre błędy pisowni, szybsza funkcja poniżej stała się dokładniejsza (?) funkcja powyżej. $dict musi być ręcznie dopasowany, oczywiście.

Poprzednia odpowiedź

Proste podejście:

// 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

Zauważ, że być może będziesz musiał najpierw urldecode() adres URL, ponieważ %20 i + są w rzeczywistości spacjami - mam na myśli, jeśli masz "nigdy%20gonna%20give%20you%20up", chcesz, aby stał się nigdy-nie-da-ci-up, a nie Never20gonna20give20you20up . Może tego nie potrzebujesz, ale pomyślałem, że wspomnę o takiej możliwości.

Więc skończona funkcja wraz z przypadkami testowymi:

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

Do obsługi UTF-8 użyłem cleanString implementacji znalezionej w Internecie (link uszkodzony od czasu, ale rozebrana Kopia z całym niezbyt ezoterycznym UTF8 znaki jest na początku odpowiedzi; łatwo jest też dodać do niej więcej znaków, jeśli potrzebujesz), który konwertuje znaki UTF8 na normalne znaki, zachowując w ten sposób słowo "look" w jak największym stopniu. Może być uproszczony i zawinięty wewnątrz funkcji tutaj dla wydajności.

Powyższa funkcja również implementuje konwersję na małe litery - ale to jest smak. Kod do tego został skomentowany.

 116
Author: LSerni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-19 20:11:04

Tutaj, sprawdź tę funkcję:

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, '-'));
}
 46
Author: Jeffrey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-01 21:35:38