Just add a space to your group:

$string = preg_replace('/[^\da-z ]/i', '', $string);
//                              ^ Notice the space here
Answer from Joseph Silber on Stack Overflow
🌐
CodexWorld
codexworld.com › home › how to guides › how to remove special characters from string in php
How to Remove Special Characters from String in PHP - CodexWorld
September 13, 2018 - Use preg_replace() function to remove special characters from string in PHP. Removes the special characters from string except space with the regular expression (Regex) using PHP.
🌐
Talkerscode
talkerscode.com › howto › php-remove-special-characters-from-string-except-space.php
PHP Remove Special Characters From String Except Space
When we use inbuilt function in php it saves time and has no complexity for handling. Here we used preg_replace() inbuilt function for removing special characters except space on string.
🌐
GitHub
gist.github.com › rahuldadhich › 34ad681ebe3a7bd57da416cceba89d31
PHP - Remove all special characters including white space, multiple space · GitHub
PHP - Remove all special characters including white space, multiple space · Raw · clear-string.php · This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
🌐
Alvin Alexander
alvinalexander.com › php › php-string-strip-characters-whitespace-numbers
PHP: How to strip unwanted characters from a string | alvinalexander.com
February 3, 2024 - $res = preg_replace("/[^a-zA-Z0-9\s]/", "", $string); (Again, I leave that output as "an exercise for the reader.") Before I go, I thought it might help to share the PHP function I wrote recently that led to this blog post.
🌐
GeeksforGeeks
geeksforgeeks.org › php › how-to-remove-special-character-from-string-in-php
How to Remove Special Character from String in PHP? - GeeksforGeeks
September 10, 2024 - The str_ireplace() method is used to remove all the special characters from the given string str by replacing these characters with the white space (" "). The difference between str_replace and str_ireplace is that str_ireplace is case-insensitive. ...
🌐
Clue Mediator
cluemediator.com › how-to-remove-special-characters-from-a-string-keeping-spaces-in-php
How to Remove Special Characters from a String (Keeping Spaces) in PHP - Clue Mediator
August 6, 2023 - This pattern matches any character that is not an uppercase or lowercase letter, a number, or a space (\s). The preg_replace function replaces all the matches with an empty string, effectively removing the special characters while preserving spaces in the string.
🌐
IQCode
iqcode.com › code › php › php-strip-out-special-characters
php strip out special characters Code Example
January 21, 2022 - function clean($string) { $string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens. return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars. } ... phpCopy<?php $mainstr = "<h2>Welcome to <b>PHPWorld</b></h2>"; ...
Find elsewhere
Top answer
1 of 3
837

This should do what you're looking for:

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

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

Usage:

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

Will output: abcdef-g

Edit:

Hey, just a quick question, how can I prevent multiple hyphens from being next to each other? and have them replaced with just 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 of 3
142

improved clean-up

The solution below has a "SEO friendlier" version:

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

The rationale for the above functions (which I find way inefficient - the one below is better) is that a service that shall not be named apparently ran spelling checks and keyword recognition on the URLs.

After losing a long time on a customer's paranoias, I found out they were not imagining things after all -- their SEO experts [I am definitely not one] reported that, say, converting "Viaggi Economy Perù" to viaggi-economy-peru "behaved better" than viaggi-economy-per (the previous "cleaning" removed UTF8 characters; Bogotà became bogot, Medellìn became medelln and so on).

There were also some common misspellings that seemed to influence the results, and the only explanation that made sense to me is that our URL were being unpacked, the words singled out, and used to drive God knows what ranking algorithms. And those algorithms apparently had been fed with UTF8-cleaned strings, so that "Perù" became "Peru" instead of "Per". "Per" did not match and sort of took it in the neck.

In order to both keep UTF8 characters and replace some misspellings, the faster function below became the more accurate (?) function above. $dict needs to be hand tailored, of course.

Previous answer

A simple approach:

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

Note that you might have to first urldecode() the URL, since %20 and + both are actually spaces - I mean, if you have "Never%20gonna%20give%20you%20up" you want it to become Never-gonna-give-you-up, not Never20gonna20give20you20up . You might not need it, but I thought I'd mention the possibility.

So the finished function along with test cases:

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

To handle UTF-8 I used a cleanString implementation found online (link broken since, but a stripped down copy with all the not-too-esoteric UTF8 characters is at the beginning of the answer; it's also easy to add more characters to it if you need) that converts UTF8 characters to normal characters, thus preserving the word "look" as much as possible. It could be simplified and wrapped inside the function here for performance.

The function above also implements converting to lowercase - but that's a taste. The code to do so has been commented out.

🌐
W3Resource
w3resource.com › php-exercises › php-regular-expression-exercise-7.php
PHP Regular Expression Exercise: Remove all characters from a string except a-z A-Z 0-9 or blank - w3resource
March 31, 2026 - The above PHP code takes a string as input, removes all characters except letters (both uppercase and lowercase), numbers, and spaces using a regular expression, and then prints both the original string and the modified string.
🌐
PHP Freaks
forums.phpfreaks.com › php coding › php coding help
preg_replace remove special characters - PHP Coding Help - PHP Freaks
December 15, 2022 - $string = "t*e*s*t"; $pattern = "/[^A-Za-zÀ-ÿ0-9\-\_\(\)\[\]\{\} ]/"; // keep all language letters, numbers, all types of brackets, spaces, hyphen, dash fullstop $cleanStr = preg_replace($pattern, '', $string); echo("{" . $cleanStr . "}"); I do not understand why this is not working, apart from t...
🌐
SitePoint
sitepoint.com › php
Help with regexes code for preg_replace - PHP - SitePoint Forums | Web Development & Design Community
December 7, 2022 - I have read some tutorials on the formatting / syntax of regexes, but it is way too far over my comprehension abilities as a new coder. I want to create a code that will do these these things: Remove most special characters (all special characters except _ - &) Convert Ampersand (&) to “and” ...
🌐
Linux Hint
linuxhint.com › remove_special_characters_string_php
Linux Hint – Linux Hint
November 1, 2020 - Linux Hint LLC, [email protected] 1210 Kelly Park Circle, Morgan Hill, CA 95037 Privacy Policy and Terms of Use
🌐
sebhastian
sebhastian.com › php-remove-special-characters
Remove special characters from a PHP string | sebhastian
November 28, 2022 - Then, pass the replacement for the special characters as the second argument. Finally, pass the original string as the third argument: <?php $string = "<removing> ,special !!characters"; $new_string = str_replace( [",", "<", ">", "!"], // 1. special chars to remove "", // 2.
🌐
W3Resource
w3resource.com › php-exercises › php-regular-expression-exercise-4.php
PHP Regular Expression Exercise: Remove nonnumeric characters except comma and dot - w3resource
March 31, 2026 - // The replacement parameter is an empty string, effectively removing all non-digit, comma, and period characters. echo preg_replace("/[^0-9,.]/", "", $str1)."\n"; ?> ... The given PHP code removes all characters except digits (0-9), comma (,), ...
🌐
IncludeHelp
includehelp.com › php › program-to-remove-special-characters-from-a-string.aspx
PHP program to remove special characters from a string
<?php #string $str = 'We welcome all of you to our school (of PHP). This--> school is one of its kind :). Many schools dont offer this subject :('; $str = preg_replace('/[^A-Za-z0-9]/', '', $str); // Printing the result echo $str; ?> WewelcomeallofyoutoourschoolofPHPThisschoolisoneofitskindManyschoolsdontofferthissubject · This is not common but it has its own importance. This differs from the first method in the sense that here programmer defines the special characters.
🌐
Delft Stack
delftstack.com › home › howto › php › remove special characters from string php
How to Remove Special Character in PHP | Delft Stack
February 2, 2024 - $search_str: It contains such value which we want to search in the given string. $replace_str: It stores a value that you want to replace, or you can also leave it empty if you only want the removal of a special character. ... See the example code. <?php $mainstr = "This is a sim'ple text;"; echo "Text before remove: \n" .