Verwijder alle speciale tekens uit een string

Ik heb een probleem met URL’s. Ik wil titels kunnen converteren die van alles kunnen bevatten en ze ontdaan van alle speciale tekens, zodat ze alleen letters en cijfers hebben en natuurlijk wil ik spaties vervangen door koppeltekens.

Hoe zou dit worden gedaan? Ik heb veel gehoord over het gebruik van reguliere expressies (regex)…


Antwoord 1, autoriteit 100%

Dit zou moeten doen wat u zoekt:

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

Gebruik:

echo clean('a|"[email protected]£de^&$f g');

Geef op: abcdef-g

Bewerken:

Hé, even een korte vraag, hoe kan ik voorkomen dat meerdere koppeltekens naast elkaar staan? en hebben ze vervangen door slechts 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.
}

Antwoord 2, autoriteit 17%

Bijwerken

De onderstaande oplossing heeft een “SEO-vriendelijkere” versie:

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);
}

De reden voor de bovenstaande functies (die ik veelinefficiënt vind – de onderstaande is beter) is dat een service die niet genoemd mag wordenblijkbaar spellingcontroles heeft uitgevoerd en zoekwoordherkenning op de URL’s.

Na een lange tijd verloren te zijn gegaan aan de paranoia’s van een klant, kwam ik erachter dat ze zich nietdingen verbeeldden — hun SEO-experts [ik ben er absoluut geen] meldden dat, laten we zeggen, het converteren van “Viaggi Economy Perù” to viaggi-economy-peru“gedroegen zich beter” dan viaggi-economy-per(de vorige “opschoning” verwijderde UTF8-tekens; Bogotàwerd bogot, Medellìnwerd medellnenzovoort).

Er waren ook enkele veelvoorkomende spelfouten die de resultaten leken te beïnvloeden, en de enige verklaring die voor mij logisch was, is dat onze URL werd uitgepakt, de woorden werden uitgekozen en gebruikt om God weet welke rangschikkingsalgoritmen aan te sturen. En die algoritmen waren blijkbaar gevoed met UTF8-opgeschoonde strings, zodat “Perù” “Peru” werd in plaats van “Per”. “Per” kwam niet overeen en nam het min of meer in de nek.

Om zowel UTF8-tekens te behouden als enkele spelfouten te vervangen, werd de snellere functie hieronder de nauwkeurigere (?) functie hierboven. $dictmoet natuurlijk met de hand worden gemaakt.

Vorige antwoord

Een eenvoudige aanpak:

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

Houd er rekening mee dat u mogelijk eerst de URL moet urldecode(), aangezien %20 en + beide feitelijk spaties zijn – ik bedoel, als u “Never%20gonna%20give%20you%20up” heeft je wilt dat het Never-gonna-give-you-up wordt, niet Never20gonna20give20you20up. Je hebt het misschien niet nodig, maar ik dacht dat ik de mogelijkheid zou noemen.

Dus de voltooide functie samen met testgevallen:

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

Om met UTF-8 om te gaan, gebruikte ik een cleanString-implementatie die ik online vond (link is sindsdien verbroken, maar een uitgeklede kopie met alle niet al te esoterische UTF8-tekens staat aan het begin van het antwoord; het is ook gemakkelijk om er meer tekens aan toe te voegen als dat nodig is) dat UTF8-tekens omzet in normale tekens, waardoor het woord “look” zoveel mogelijk behouden blijft. Het kan worden vereenvoudigd en hier in de functie worden verpakt voor prestaties.

De bovenstaande functie implementeert ook het converteren naar kleine letters – maar dat is een voorproefje. De code om dit te doen is als commentaar verwijderd.


Antwoord 3, autoriteit 7%

Kijk hier eens naar deze functie:

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

Other episodes