Функция для возврата только буквенно-цифровых символов из строки?


100

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

Мне нужна вторая функция, которая делает то же самое, но возвращает только буквенные символы AZ.

Любая помощь очень ценится.


В какой форме нормализации Unicode они находятся и зачем вам это нужно?
tchrist 04

1
Когда вы говорите «А-Я» и «буквенно-цифровой», вы действительно имеете в виду только А-Я или вы хотите сопоставить все буквы всех языков, включая иностранные языки и устаревшие шрифты?
Марк Байерс

Если вы делаете это для сравнения строк без учета акцента, вы делаете неправильные вещи.
tchrist 04

3
Это не просто «со всех языков». Это английский. Английский использует латинский алфавит. Есть unichars '\p{Latin}' '\p{Alphabetic}' '[^A-Za-z]' | wc -l== 1192 кодовых точки, которые являются латинскими буквами, но не являются AZ. Принято считать, что для английского языка достаточно ASCII. Это не так, и поэтому написание AZ имеет запах кода .
tchrist 04

1
@Scott B: английский не просто использует 26 букв от А до Я. Например, слово резюме включает é. Возможно, вы могли бы объяснить, что вы пытаетесь сделать, поскольку это может помочь вам получить более точные ответы.
Марк Байерс

Ответы:


216

Предупреждение: обратите внимание, что английский не ограничивается только AZ.

Попробуйте это , чтобы удалить все , кроме аз, AZ и 0-9:

$result = preg_replace("/[^a-zA-Z0-9]+/", "", $s);

Если ваше определение буквенно-цифрового включает буквы на иностранных языках и устаревшие сценарии, тогда вам нужно будет использовать классы символов Unicode.

Попробуйте это оставить только AZ:

$result = preg_replace("/[^A-Z]+/", "", $s);

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


2
Нет, буквенно-цифровой [\p{Alphabetic}\p{Numeric}]. Я забыл об алфавитном свойстве PCRE, но вы можете приблизить его с помощью [\pL\pM\pN].
tchrist 04

1
@tchrist: Я предполагаю, что, поскольку он специально упомянул АЗ, он хочет только сопоставить это, хотя я допускаю, что вопрос может быть намного более ясным по этому поводу. Прошу пояснений.
Марк Байерс

1
@Mark, я не спорил со второй частью вашего ответа, хотя, если он сначала не разложил строку канонически, это не сработает. Я спорил с первой частью. Кроме того, я стараюсь всегда исправлять регулярные выражения, которые работают с любыми данными, а не только с заплесневелым старым ASCII. :) Отсюда мантра о том, что по эту сторону Миллениума [A-Z], иногда бывает неверно .
tchrist

1
@Mark Byers, я понимаю ... и да, я предпочитаю, iно мне всегда приходилось беспокоиться только об английской демографии ... Я забываю, что многим людям приходится думать о других языках. Кстати, я только что заметил, что вы самый известный пользователь, который никогда не задавал ни одного вопроса. Даже Джон Скит раньше задавал вопросы!
Джей Ди Айзекс 04

1
почему в конце регулярного выражения стоит +? Разве не было бы ... того же, если бы вы его удалили?
Деннис

2

Вместо preg_replaceэтого вы всегда можете использовать функции фильтрации PHP, используя filter_var()функцию с расширением FILTER_SANITIZE_STRING.


Есть ли у PHP доступ к алгоритму ISO Stringprep? Я знаю, что это делают Perl и Java.
tchrist

Я считаю, что функция строкового фильтра работает преимущественно с 7-битным ASCII, но не цитируйте меня по этому поводу.
Марк Бейкер,

30
Пожалуйста, не могли бы вы указать нам явный способ сделать то, что пользователь просит использовать FILTER_SANITIZE_STRING? Насколько мне известно, самое близкое, что можно получить таким образом, - это с FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH, но при этом останутся не только буквы и цифры, но также точки, косые черты, проценты и все такое.
Pere

$ iMycleanVar = filter_var ($ sStringWithNumbers, FILTER_SANITIZE_NUMBER_INT);
Султанос

4
Это больше похоже на комментарий, чем на ответ. При написании ответа дайте правильное объяснение.
Сирадж Алам

0
  1. Santize для чисел [ 0-9 ] и алфавитов в целом [ \ pL ]:
$string = preg_replace("/[^0-9\pL]+/", "", $string)
  1. Santize специально для алфавитов от A до Z ( без учета регистра) [ a-zA-Z ]:
$string = preg_replace("/[^a-zA-Z]+/", "", $string)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.