Как удалить не алфавитно-цифровые символы?

349

Мне нужно удалить все символы из строки, которые не в a-z A-Z 0-9наборе или не являются пробелами.

У кого-нибудь есть функция для этого?

zuk1
источник

Ответы:

695

Похоже, вы почти знали, что вы уже хотели делать, вы в основном определили это как регулярное выражение.

preg_replace("/[^A-Za-z0-9 ]/", '', $string);
Чад берез
источник
8
zuk1: regexbuddy очень помогает в этом
relipse
2
Вот пример, если вы хотите включить дефис в качестве разрешенного символа. Мне это нужно, потому что мне нужно было удалить запрещенные символы из имени пользователя Moodle на основе адресов электронной почты: preg_replace ("/ [^ a-z0-9 _. @ \ -] /", '', $ string);
Эван Донован
2
Будет ли это работать точно так же с апострофами (одинарными кавычками) вокруг регулярного выражения вместо кавычек (двойных кавычек)? Например:preg_replace('/[^A-Za-z0-9 ]/', '', $string);
2540625
3
Мы хотим объяснения по этому поводу :). Люди приходят сюда, чтобы понять, почему это так. Пожалуйста, рассмотрите объяснение Regex тоже! Спасибо
Пратик
1
Что если мы хотим сохранить акцент на персонажах?
Wonzbak
169

Для символов Юникода это:

preg_replace("/[^[:alnum:][:space:]]/u", '', $string);
voondo
источник
привет voondo, что с / UI вещь .. как вы это называете? Может кто-нибудь, пожалуйста, пролить мне немного света. Спасибо.
Kebyang
4
Для пояснения они называются флагами. Они помещаются после закрывающего разделителя (в данном случае это «/», но это может быть «~» или «@» или любой другой символ, который вы хотите использовать, если открывающий и закрывающий разделители совпадают) и изменяют поведение выражения.
Доктор J
1
Кстати, \wвключает \dи так \dненужно. Кроме того, это неправильно, потому что это также оставит подчеркивание в результирующей строке (которая также включена в \w).
Smathy
2
В этом все еще есть ошибка, классы символов должны заканчиваться символом ':], поэтому правильная строка будет выглядеть так: preg_replace ("/ [^ [: alnum:] [: space:]] / ui",' ', $ string);
h00ligan
4
Действительно ли iфлаг здесь необходим, поскольку [:alnum:]уже охватывает оба случая?
Биллиноа
50

Регулярное выражение ваш ответ.

$str = preg_replace('/[^a-z\d ]/i', '', $str);
  • iОзначает нечувствительны к регистру.
  • ^ значит, не начинается с.
  • \d соответствует любой цифре.
  • a-zсоответствует всем символам между aи z. Из-за iпараметра вам не нужно указывать a-zи A-Z.
  • После \dпробела допускаются пробелы в этом регулярном выражении.
raspi
источник
3
Мы хотим объяснения по этому поводу :). Люди приходят сюда, чтобы понять, почему это так. Пожалуйста, рассмотрите объяснение Regex тоже! Не каждый достаточно продвинут, чтобы знать, что вы там написали без объяснения причин. Спасибо
Пратик
@PratikCJoshi Я стоит без учета регистра. ^ означает, не начинается с. \ d соответствует любой цифре. az соответствует всем символам между a и z. Из-за параметра i вам не нужно указывать az и AZ. После \ d есть пробел, поэтому пробелы разрешены в этом регулярном выражении.
Барт
1
Люди не читают комментарии как ответ. Пожалуйста, обновите ответ!
Пратик
18

вот действительно простое выражение для этого:

\W|_

и используется по мере необходимости (с /разделителем косой черты).

preg_replace("/\W|_/", '', $string);

Проверьте это здесь с помощью этого замечательного инструмента, который объясняет, что делает регулярное выражение:

http://www.regexr.com/

Алекс Стивенс
источник
1
Вам все еще нужен /uфлаг, в противном случае не-буквы ascii также удаляются.
Xeoncross
Аккуратно, но также будет соответствовать пробелам и, если это необходимо, возможно, удвоит производительность за счет использования класса символов и дополнительного квантификатора для одного или нескольких [\W_]+
всплывающий пузырь
18

Если вам требуется поддержка других языков, вместо типичного AZ, вы можете использовать следующее:

preg_replace('/[^\p{L}\p{N} ]+/', '', $string);
  • [^\p{L}\p{N} ]определяет отрицательный (он будет соответствовать символу, который не определен) класс символов:
    • \p{L}: письмо с любого языка.
    • \p{N}: числовой символ в любом скрипте.
    • : космический символ.
  • + жадно соответствует классу персонажа от 1 до неограниченного количества раз.

Это сохранит буквы и цифры из других языков и сценариев, а также AZ:

preg_replace('/[^\p{L}\p{N} ]+/', '', 'hello-world'); // helloworld
preg_replace('/[^\p{L}\p{N} ]+/', '', 'abc@~#123-+=öäå'); // abc123öäå
preg_replace('/[^\p{L}\p{N} ]+/', '', '你好世界!@£$%^&*()'); // 你好世界

Примечание: это очень старый, но все еще актуальный вопрос. Я отвечаю исключительно, чтобы предоставить дополнительную информацию, которая может быть полезна для будущих посетителей.

Джонатон
источник
8
[\W_]+

 

$string = preg_replace("/[\W_]+/u", '', $string);

Он выбирает все, а не AZ, az, 0-9 и удаляет его.

Смотрите пример здесь: https://regexr.com/3h1rj

Intacto
источник
1
что означает это регулярное выражение / [\ W _] + / u?
Анджело Риго
\Wявляется инверсией \wкоторых являются символы A-Za-z0-9_. Так \Wбудет соответствовать любой символ, которого нет, A-Za-z0-9_и удалить их. []Является набор символов границы . Это +избыточно на границе набора символов, но обычно означает 1 или более символов. uФлаг расширяет выражение , чтобы включить поддержку юникода характер, то есть он не будет удалять символы за пределами кода символа 255 , например , как ª²³µ. Пример использования 3v4l.org/hSVV5 с символами Unicode и ASCII.
fyrye
2
preg_replace("/\W+/", '', $string)

Вы можете проверить это здесь: http://regexr.com/

ТОЗ
источник
Согласно @Alex Stevens, это не подчеркивает подчеркивание "_".
Ариэль Аллон
0

Я тоже искал ответ, и мое намерение состояло в том, чтобы убрать все не альфа, и там не должно быть больше одного пробела.
Итак, я изменил ответ Алекса на это, и это работает для меня preg_replace('/[^a-z|\s+]+/i', ' ', $name)
. Выражение выше обратилось sy8ed sirajul7_islamк sy ed sirajul islam
Объяснению: регулярное выражение будет проверять НЕ ЛЮБОЙ от a до z в случае нечувствительного к регистру пути или более чем один пробел, и он будет преобразован в один пространство.

ГНУ-Anik
источник
-2

Вы можете разбить строку на символы и отфильтровать ее.

<?php 

function filter_alphanum($string) {
    $characters = str_split($string);
    $alphaNumeric = array_filter($characters,"ctype_alnum");
    return join($alphaNumeric);
}

$res = filter_alphanum("a!bc!#123");
print_r($res); // abc123

?>
zekel
источник
Причина downvote: 3v4l.org/fqLVZ Кроме того, вызов (3 + N) функций для строки неизвестной длины кажется действительно непривлекательным по сравнению с одним простым preg_replace()вызовом.
mickmackusa