Регулярное выражение PHP - удаление всех не-буквенно-цифровых символов

Я использую PHP.

Моя строка может выглядеть так

This is a string-test width åäö and some über+strange characters: _like this?

Вопрос

Есть ли способ удалить не буквенно-цифровые символы и заменить их пробелом? Вот несколько не буквенно-цифровых символов:

  • -
  • +
  • _

Я прочитал много потоков об этом, но они не поддерживают другие языки, такие как этот:

preg_replace("/[^A-Za-z0-9 ]/", '', $string);

Требования

  • Мой список букв не может быть завершен.
  • Мое содержимое содержит символы на разных языках, например, åäöü. Может быть очень много.
  • Не буквенно-цифровые символы должны быть заменены пробелом. Иначе слово будет приклеено к друг другу.

Ответ 1

Вы можете попробовать следующее:

preg_replace('~[^\p{L}\p{N}]++~u', ' ', $string);

\p{L} обозначает все алфавитные символы (независимо от алфавита).

\p{N} обозначает числа.

С символами-модификаторами u предметной строки рассматриваются как символы Unicode.

Или это:

preg_replace('~\P{Xan}++~u', ' ', $string);

\p{Xan} содержит символы и цифры в Юникоде.

\p{Xan} содержит все, что не является символами и цифрами Unicode. (Будьте осторожны, он также содержит белые пробелы, которые можно сохранить с помощью ~[^\p{Xan}\s]++~u)

Если вам нужен более конкретный набор разрешенных букв, вы должны заменить \p{L} диапазонами в таблице unicode.

Пример:

preg_replace('~[^a-zÀ-ÖØ-öÿŸ\d]++~ui', ' ', $string);

Зачем использовать притяжательный квантификатор (++) здесь?

~\P{Xan}+~u даст вам тот же результат, что и ~\P{Xan}++~u. Разница здесь в том, что в первом случае двигатель записывает каждое положение возврата (что нам не нужно), когда во втором он не имеет (как в атомной группе). В результате получается небольшая прибыль.

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

Однако, механизм регулярного выражения PCRE автоматически использует квантификатор в очевидных ситуациях (пример: a+b = > a++b), за исключением того, что модуль PCRE был скомпилирован с параметром PCRE_NO_AUTO_POSSESS. (http://www.pcre.org/pcre.txt)

Более подробная информация о притяжательных квантификаторах и атомных группах здесь (притяжательные квантификаторы) и здесь (атомные группы) или здесь

Ответ 2

Возможно, вы ищете \W?

Что-то вроде:

/[\W_]*/

Совпадает со всеми не-буквенно-цифровыми символами и символами подчеркивания.

\W соответствует всем символам слова (алфавиту, числовому, подчеркиванию)

\W соответствует чему-либо не в \W.

Итак, \W соответствует любым несимвольным символам, и вы добавляете символ подчеркивания, так как \W не соответствует символам подчеркивания.

EDIT: это сделает вашу строку кода следующей:

preg_replace("/[\W_]*/", ' ', $string);

' ' означает, что все совпадающие символы (те, что не являются буквой, а не цифрой) становятся белыми.

reEDIT: вы можете дополнительно использовать другой preg_replace, чтобы удалить все последовательные пробелы и заменить их одним пробелом, иначе вы получите:

This is a string test width     and some  ber strange characters   like this 

Вы можете использовать:

preg_replace("/\s+/", ' ', $string);

И, наконец, обрезайте начальное и конечное пространства, если они есть.

Ответ 3

Я не совсем уверен, какое множество регулярных выражений вы используете. Однако, регулярные выражения POSIX позволяют вам выражать алфавитный класс, где [: alpha:] представляет любой буквенный символ.

Итак, попробуйте:

preg_replace("/[^[:alpha:]0-9 ]/", '', $string);

Собственно, я забыл про [: alnum:] - это упрощает:

preg_replace("/[^[:alnum:] ]/", '', $string);

Ответ 4

\p{xx} - это то, что вы ищете, я считаю, см. здесь

Итак, попробуйте:

preg_replace("/\P{L}+/u", ' ', $string);