Удалить управляющие символы из строки PHP
Как удалить управляющие символы, такие как STX, из строки PHP? Я играл с
preg_replace("/[^a-zA-Z0-9 .\-_;!:?äÄöÖüÜß<>='\"]/","",$pString)
но обнаружил, что это отодвинуло многое. Есть ли способ удалить только контрольные символы?
6 ответов
Если вы подразумеваете под управляющими символами первые 32 символа ascii и \x7F
(включая возврат каретки и т. д.!), тогда это будет работать:
preg_replace('/[\x00-\x1F\x7F]/', '', $input);
(Обратите внимание на одинарные кавычки: с двойными кавычками использование \x00
как-то вызывает ошибку разбора.)
Перевод строки и возврат каретки (часто пишется \r
а также \n
) может быть спасен от удаления следующим образом:
preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/', '', $input);
Я должен сказать, что я думаю, что ответ Бобби лучше, в том смысле, что [:cntrl:]
лучше передает то, что делает код, чем [\x00-\x1F\x7F]
,
ПРЕДУПРЕЖДЕНИЕ: ereg_replace
устарела в PHP >= 5.3.0 и удалена в PHP >= 7.0.0!, пожалуйста, используйте preg_replace
вместо ereg_replace
:
preg_replace('/[[:cntrl:]]/', '', $input);
При вводе Unicode это удалит все входные символы из управляющего символа, неназначенного, личного использования, форматирования и суррогатных кодовых точек (которые также не являются пробелами, такими как табуляция, новая строка). Я использую это, чтобы удалить все непечатаемые символы из моего ввода.
<?php
$clean = preg_replace('/[^\PC\s]/u', '', $input);
для получения дополнительной информации о \p{C}
см. http://www.regular-expressions.info/unicode.html
PHP поддерживает POSIX-классы, так что вы можете использовать [:cntrl:]
вместо какого-то необычного персонажа-магии:
ereg_replace("[:cntrl:]", "", $pString);
Редактировать:
В 5.3 может потребоваться дополнительная пара квадратных скобок.
ereg_replace("[[:cntrl:]]", "", $pString);
Ответ TLDR
Используйте это регулярное выражение...
/[^\PCc^\PCn^\PCs]/u
Как это...
$text = preg_replace('/[^\PCc^\PCn^\PCs]/u', '', $text);
Объяснение TLDR
- : Не совпадать с управляющими символами.
-
^\PCn
: не совпадать с неназначенными символами. -
^\PCs
: не совпадать с недопустимыми символами UTF-8.
Рабочая демонстрация
Простая демонстрация для демонстрации: IDEOne Demo
$text = "\u{0019}hello";
print($text . "\n\n");
$text = preg_replace('/[^\PCc^\PCn^\PCs]/u', '', $text);
print($text);
Выход:
(-Broken-Character)hello
hello
Альтернативы
- : Соответствие только видимым символам. Не совпадайте с невидимыми символами.
-
^\PCc
: Соответствие только неуправляющим символам. Не совпадайте ни с какими управляющими символами. -
^\PCc^\PCn
: Совпадение только с назначенными неуправляющими символами. Не совпадайте ни с какими управляющими или неназначенными символами. -
^\PCc^\PCn^\PCs
: Совпадение только с неуправляющими символами, которые были назначены и являются допустимыми в кодировке UTF-8. Не совпадайте ни с какими управляющими, неназначенными или недопустимыми символами UTF-8. -
^\PCc^\PCn^\PCs^\PCf
: Соответствие только неуправляющим, неформатирующим символам, которые были назначены и являются допустимыми в кодировке UTF-8. Не совпадайте ни с какими управляющими, неназначенными, форматирующими или недопустимыми символами UTF-8.
Источник и объяснение
Взгляните на доступные свойства символов Unicode , которые можно использовать для тестирования в регулярном выражении. Вы должны иметь возможность использовать эти регулярные выражения в Microsoft .NET, JavaScript, Python, Java, PHP, Ruby, Perl, Golang и даже . Знание классов символов Unicode — очень полезное знание, поэтому я рекомендую его использовать!
Это регулярное выражение будет соответствовать всему видимому, указанному как в сокращенной, так и в длинной форме...
\PL\PM\PN\PP\PS\PZ
\PLetter\PMark\PNumber\PPunctuation\PSymbol\PSeparator
Обычно,
\p
указывает, что это то, что мы хотим сопоставить, и мы используем
\P
(с заглавной буквы) Adobeдля обозначения того, что не соответствует. Но PHP не имеет этой функциональности, поэтому нам нужно использовать
^
в регулярном выражении для ручного отрицания.
Тогда более простым регулярным выражением будет
^\PC
, но это может быть слишком ограничивающим при удалении невидимого форматирования. Вы можете внимательно присмотреться и посмотреть, что лучше, но один из вариантов должен соответствовать вашим потребностям.
Все совместимые наборы символов Unicode
Если вы хотите узнать о других доступных наборах символов, загляните на сайт регулярных выражений.info ...
-
\PL
или же\PLetter
: любое письмо с любого языка.-
\PLl
или же\PLowercase_Letter
: строчная буква, у которой есть вариант в верхнем регистре. -
\PLu
или же\PUppercase_Letter
: заглавная буква, у которой есть строчный вариант. -
\PLt
или же\PTitlecase_Letter
: буква, которая появляется в начале слова, когда только первая буква слова заглавная. -
\PL&
или же\PCased_Letter
: буква, которая существует в строчных и прописных вариантах (сочетание Ll, Lu и Lt). -
\PLm
или же\PModifier_Letter
: специальный символ, который используется как буква. -
\PLo
или же\POther_Letter
: буква или идеограмма, в которой нет строчных и прописных букв.
-
-
\PM
или же\PMark
: символ, предназначенный для комбинирования с другим символом (например, акценты, умлауты, заключающие квадраты и т. д.).-
\PMn
или же\PNon_Spacing_Mark
: символ, предназначенный для объединения с другим символом, не занимая лишнего места (например, акценты, умлауты и т. д.). -
\PMc
или же\PSpacing_Combining_Mark
: символ, предназначенный для объединения с другим символом, занимающим дополнительное место (знаки гласных во многих восточных языках). -
\PMe
или же\PEnclosing_Mark
: символ, заключающий в себе символ, с которым он сочетается (круг, квадрат, колпачок и т. д.).
-
-
\PZ
или же\PSeparator
: любой вид пробела или невидимого разделителя.-
\PZs
или же\PSpace_Separator
: символ пробела, невидимый, но занимающий место. -
\PZl
или же\PLine_Separator
: символ-разделитель строк U+2028. -
\PZp
или же\PParagraph_Separator
: символ-разделитель абзаца U+2029.
-
-
\PS
или же\PSymbol
: математические символы, знаки валюты, дингбаты, символы для рисования коробок и т. д.-
\PSm
или же\PMath_Symbol
: любой математический символ. -
\PSc
или же\PCurrency_Symbol
: любой знак валюты. -
\PSk
или же\PModifier_Symbol
: объединяющий символ (отметка) как самостоятельный полный символ. -
\PSo
или же\POther_Symbol
: различные символы, не являющиеся математическими символами, знаками валюты или комбинацией символов.
-
-
\PN
или же\PNumber
: любой числовой символ в любом сценарии.-
\PNd
или же\PDecimal_Digit_Number
: цифра от нуля до девяти в любом письме, кроме идеографического письма. -
\PNl
или же\PLetter_Number
: число, похожее на букву, например римскую цифру. -
\PNo
или же\POther_Number
: цифра надстрочного или подстрочного индекса или число, не являющееся цифрой 0–9 (за исключением чисел из идеографического письма).
-
-
\PP
или же\PPunctuation
: любой знак пунктуации.-
\PPd
или же\PDash_Punctuation
: любой вид дефиса или тире. -
\PPs
или же\POpen_Punctuation
: любая открывающая скобка. -
\PPe
или же\PClose_Punctuation
: любая закрывающая скобка. -
\PPi
или же\PInitial_Punctuation
: любая вступительная цитата. -
\PPf
или же\PFinal_Punctuation
: любая заключительная цитата. -
\PPc
или же\PConnector_Punctuation
: знак пунктуации, например знак подчеркивания, соединяющий слова. -
\PPo
или же\POther_Punctuation
: любой знак пунктуации, кроме тире, квадратных скобок, кавычек или соединительных элементов.
-
-
\PC
или же\POther
: невидимые управляющие символы и неиспользуемые кодовые точки.-
\PCc
или же\PControl
: управляющий символ ASCII или Latin-1: 0x00–0x1F и 0x7F–0x9F. -
\PCf
или же\PFormat
: невидимый индикатор форматирования. -
\PCo
или же\PPrivate_Use
: любая кодовая точка, зарезервированная для частного использования. -
\PCs
или же\PSurrogate
: половина суррогатной пары в кодировке UTF-16. -
\PCn
или же\PUnassigned
: любая кодовая точка, которой не назначен ни один символ.
-
Чтобы сохранить управляющие символы, но сделать их совместимыми с JSON, мне пришлось
$str = preg_replace(
array(
'/\x00/', '/\x01/', '/\x02/', '/\x03/', '/\x04/',
'/\x05/', '/\x06/', '/\x07/', '/\x08/', '/\x09/', '/\x0A/',
'/\x0B/','/\x0C/','/\x0D/', '/\x0E/', '/\x0F/', '/\x10/', '/\x11/',
'/\x12/','/\x13/','/\x14/','/\x15/', '/\x16/', '/\x17/', '/\x18/',
'/\x19/','/\x1A/','/\x1B/','/\x1C/','/\x1D/', '/\x1E/', '/\x1F/'
),
array(
"\u0000", "\u0001", "\u0002", "\u0003", "\u0004",
"\u0005", "\u0006", "\u0007", "\u0008", "\u0009", "\u000A",
"\u000B", "\u000C", "\u000D", "\u000E", "\u000F", "\u0010", "\u0011",
"\u0012", "\u0013", "\u0014", "\u0015", "\u0016", "\u0017", "\u0018",
"\u0019", "\u001A", "\u001B", "\u001C", "\u001D", "\u001E", "\u001F"
),
$str
);
(Правила JSON гласят: "Все символы Юникода могут быть помещены в кавычки, кроме символов, которые должны быть экранированы: кавычка, обратный солидус и управляющие символы (от U+0000 до U+001F)".)
метод регулярных выражений
Если вы используете только знакомые мне управляющие символы (те, кому меньше 32 и 127), попробуйте это:
for($control = 0; $control < 32; $control++) {
$pString = str_replace(chr($control), "", $pString;
}
$pString = str_replace(chr(127), "", $pString;
Цикл избавляет от всего, кроме DEL, который мы просто добавляем в конец.
Я думаю, что это будет намного менее напряженным для вас и для сценария, чем для регулярных выражений и библиотеки регулярных выражений.
Обновленный метод регулярных выражений
Просто ради удовольствия я придумал другой способ сделать это. Этот делает это, используя массив управляющих символов:
$ctrls = range(chr(0), chr(31));
$ctrls[] = chr(127);
$clean_string = str_replace($ctrls, "", $string);