Удалить управляющие символы из строки 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);
Другие вопросы по тегам