Reputation: 24748
I use PHP.
My string can look like this
This is a string-test width åäö and some über+strange characters: _like this?
Question
Is there a way to remove non-alphanumeric characters and replace them with a space? Here are some non-alphanumeric characters:
I've read many threads about it but they don't support other languages, like this one:
preg_replace("/[^A-Za-z0-9 ]/", '', $string);
Requirements
Upvotes: 12
Views: 20607
Reputation: 89557
You can try this:
preg_replace('~[^\p{L}\p{N}]++~u', ' ', $string);
\p{L}
stands for all alphabetic characters (whatever the alphabet).
\p{N}
stands for numbers.
With the u modifier characters of the subject string are treated as unicode characters.
Or this:
preg_replace('~\P{Xan}++~u', ' ', $string);
\p{Xan}
contains unicode letters and digits.
\P{Xan}
contains all that is not unicode letters and digits. (Be careful, it contains white spaces too that you can preserve with ~[^\p{Xan}\s]++~u
)
If you want a more specific set of allowed letters you must replace \p{L}
with ranges in unicode table.
Example:
preg_replace('~[^a-zÀ-ÖØ-öÿŸ\d]++~ui', ' ', $string);
Why using a possessive quantifier (++) here?
~\P{Xan}+~u
will give you the same result as ~\P{Xan}++~u
. The difference here is that in the first the engine records each backtracking position (that we don't need) when in the second it doesn't (as in an atomic group). The result is a small performance profit.
I think it's a good practice to use possessive quantifiers and atomic groups when it's possible.
However, the PCRE regex engine makes automatically a quantifier possessive in obvious situations (example: a+b
=> a++b
) except If the PCRE module has been compiled with the option PCRE_NO_AUTO_POSSESS. (http://www.pcre.org/pcre.txt)
More informations about possessive quantifiers and atomic groups here (possessive quantifiers) and here (atomic groups) or here
Upvotes: 33
Reputation: 33341
\p{xx}
is what you are looking for, I believe, see here
So, try:
preg_replace("/\P{L}+/u", ' ', $string);
Upvotes: 1
Reputation: 71538
Are you perhaps looking for \W
?
Something like:
/[\W_]*/
Matches all non-alphanumeric character and underscores.
\w
matches all word character (alphabet, numeric, underscores)
\W
matches anything not in \w
.
So, \W
matches any non-alphanumeric characters and you add the underscore since \W
doesn't match underscores.
EDIT: This make your line of code become:
preg_replace("/[\W_]*/", ' ', $string);
The ' '
means that all matching characters (those not letter and not number) will become white spaces.
reEDIT: You might additionally want to use another preg_replace
to remove all the consecutive spaces and replace them with a single space, otherwise you'll end up with:
This is a string test width and some ber strange characters like this
You can use:
preg_replace("/\s+/", ' ', $string);
And lastly trim the beginning and end spaces if any.
Upvotes: 3
Reputation: 5689
I am not entirely sure which variety of regex you are using. However, POSIX regexes allow you to express an alphabetical class, where [:alpha:] represents any alphabetic character.
So try:
preg_replace("/[^[:alpha:]0-9 ]/", '', $string);
Actually, I forgot about [:alnum:] - that makes it simpler:
preg_replace("/[^[:alnum:] ]/", '', $string);
Upvotes: 2