从PHP字符串中删除控制字符

KB2*_*B22 60 php regex string

如何从PHP字符串中删除STX之类的控制字符?我一起玩

preg_replace("/[^a-zA-Z0-9 .\-_;!:?äÄöÖüÜß<>='\"]/","",$pString)
Run Code Online (Sandbox Code Playgroud)

但发现它删除的方式很多.有没有办法删除 控制字符?

Ste*_*202 101

如果你的控制字符是指前32个ascii字符和\x7F(包括回车等等),那么这将起作用:

preg_replace('/[\x00-\x1F\x7F]/', '', $input);
Run Code Online (Sandbox Code Playgroud)

(注意单引号:使用双引号使用\x00会导致解析错误,不知何故.)

换行和回车(通常是写入\r\n)可以从删除中保存,如下所示:

preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/', '', $input);
Run Code Online (Sandbox Code Playgroud)

我必须说,我认为Bobby的答案更好,从某种意义上说,[:cntrl:]更能传达代码的作用[\x00-\x1F\x7F].

警告: ereg_replace在PHP> = 5.3.0中已弃用并在PHP> = 7.0.0!中删除,请使用preg_replace而不是ereg_replace:

preg_replace('/[[:cntrl:]]/', '', $input);
Run Code Online (Sandbox Code Playgroud)

  • 另外,preg_replace('/ [[:cntrl:]] /','',$ input); 为我工作很好(PHP 5.2.6). (8认同)
  • 遗憾的是,ereg_replace在PHP 5.3中已弃用,而mb版本比preg_replace慢.使用preg_replace有一种稍微更简洁的方法,在我的测试中,它比上面的更快(比处理成千上万的项目快1%):preg_replace('/ [\ p {Cc}] /','',$ input); (7认同)
  • 并不是说你也可能想要保存标签"\ t".我找到了这个问题,因为我在我的数据库中获得了\ x1D. (2认同)

Sco*_*rth 37

对于Unicode输入,这将从输入文本中删除所有控制字符,未分配,私有使用,格式化和代理代码点(也不是空格字符,例如制表符,换行符).我用它从我的输入中删除所有不可打印的字符.

<?php
$clean = preg_replace('/[^\PC\s]/u', '', $input);
Run Code Online (Sandbox Code Playgroud)

有关更多信息,\p{C}请参阅http://www.regular-expressions.info/unicode.html#category

  • 嗨@ChrisRosillo,我们使用`\ p {C}`的反形式``\ t``,所以`\ p {C}`匹配控制字符,\ PC匹配所有不是控制字符的东西.然后我们使用一个否定的字符类`[^ ..]`来表示匹配/替换任何东西"不是[不是控制字符或空格]".所以这是一种双重否定. (2认同)

Bob*_*bby 21

PHP确实支持POSIX-Classes,因此您可以使用[:cntrl:]而不是一些奇特的角色魔术:

ereg_replace("[:cntrl:]", "", $pString);
Run Code Online (Sandbox Code Playgroud)

编辑:

5.3中可能需要一对额外的方括号.

ereg_replace("[[:cntrl:]]", "", $pString);
Run Code Online (Sandbox Code Playgroud)

  • 不推荐使用ereg_replace:http://php.net/manual/zh/function.ereg-replace.php (11认同)
  • 由于 `ereg_replace` 在 PHP 7.0 中被删除,对于 PHP &gt; 7.0,它应该是: `preg_replace("/[[:cntrl:]]/", "", $input);` (2认同)

Hol*_*ger 12

TLDR 答案

\n

使用这个正则表达式...

\n
/[^\\PCc^\\PCn^\\PCs]/u\n
Run Code Online (Sandbox Code Playgroud)\n

像这样...

\n
$text = preg_replace(\'/[^\\PCc^\\PCn^\\PCs]/u\', \'\', $text);\n
Run Code Online (Sandbox Code Playgroud)\n

TLDR 解释

\n
    \n
  • ^\\PCc:匹配控制字符。
  • \n
  • ^\\PCn匹配未分配的字符。
  • \n
  • ^\\PCs匹配 UTF-8 无效字符。
  • \n
\n

工作演示

\n

简单的演示:IDEOne Demo

\n
$text = "\\u{0019}hello";\nprint($text . "\\n\\n");\n$text = preg_replace(\'/[^\\PCc^\\PCn^\\PCs]/u\', \'\', $text);\nprint($text);\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
(-Broken-Character)hello\nhello\n
Run Code Online (Sandbox Code Playgroud)\n

备择方案

\n
    \n
  • ^\\PC:仅匹配可见字符。不匹配任何不可见字符。
  • \n
  • ^\\PCc:仅匹配非控制字符。不匹配任何控制字符。
  • \n
  • ^\\PCc^\\PCn:仅匹配已分配的非控制字符。不匹配任何控制字符或未分配的字符。
  • \n
  • ^\\PCc^\\PCn^\\PCs:仅匹配已分配且 UTF-8 有效的非控制字符。不匹配任何控制字符、未分配字符或 UTF-8 无效字符。
  • \n
  • ^\\PCc^\\PCn^\\PCs^\\PCf:仅匹配已分配且 UTF-8 有效的非控制、非格式化字符。不匹配任何控制字符、未分配字符、格式化字符或 UTF-8 无效字符。
  • \n
\n

来源及解释

\n

查看可用于在正则表达式中测试的可用Unicode 字符属性。您应该能够在Microsoft .NETJavaScriptPythonJavaPHPRubyPerlGolang甚至Adob​​e中使用这些正则表达式。了解 Unicode 字符类是非常可转移的知识,所以我建议使用它!

\n

该正则表达式将匹配任何可见的内容,以简写形式和长写形式给出......

\n
\\PL\\PM\\PN\\PP\\PS\\PZ\n\\PLetter\\PMark\\PNumber\\PPunctuation\\PSymbol\\PSeparator\n
Run Code Online (Sandbox Code Playgroud)\n

通常,\\p表示我们想要匹配的内容,而我们使用\\P(大写)来表示不匹配的内容。 但是PHP没有这个功能,所以我们需要^在正则表达式中进行手动否定。

\n

一个更简单的正则表达式是^\\PC,但这在删除不可见格式方面可能过于严格。您可能想仔细观察并看看什么是最好的,但其中一种替代方案应该可以满足您的需求。

\n

所有可匹配的 Unicode 字符集

\n

如果您想了解任何其他可用的字符集,请查看regular-expressions.info ...

\n
    \n
  • \\PL\\PLetter: 来自任何语言的任何类型的字母。\n
      \n
    • \\PLl\\PLowercase_Letter:具有大写变体的小写字母。
    • \n
    • \\PLu\\PUppercase_Letter:具有小写变体的大写字母。
    • \n
    • \\PLt\\PTitlecase_Letter:仅当单词的第一个字母大写时出现在单词开头的字母。
    • \n
    • \\PL&\\PCased_Letter:存在小写和大写变体的字母(Ll、Lu 和 Lt 的组合)。
    • \n
    • \\PLm\\PModifier_Letter:像字母一样使用的特殊字符。
    • \n
    • \\PLo\\POther_Letter:没有小写和大写的字母或表意文字
    • \n
    \n
  • \n
  • \\PM\\PMark: 打算与另一个字符组合的字符(例如重音符号、变音符号、封闭框等)。\n
      \n
    • \\PMn\\PNon_Spacing_Mark:打算与另一个字符组合\n而不占用额外空间的字符(例如重音符号、变音符号等)。
    • \n
    • \\PMc\\PSpacing_Combining_Mark:旨在与占用额外空间的另一个字符(许多东方语言中的元音符号)组合的字符。
    • \n
    • \\PMe\\PEnclosing_Mark:包含与其组合的字符的字符(圆形、方形、键帽等)。
    • \n
    \n
  • \n
  • \\PZ\\PSeparator: 任何类型的空格或不可见的分隔符。\n
      \n
    • \\PZs或者\\PSpace_Separator:不可见但占用空间的空白字符。
    • \n
    • \\PZl或者\\PLine_Separator:行分隔符 U+2028。
    • \n
    • \\PZp或者\\PParagraph_Separator:段落分隔符 U+2029。
    • \n
    \n
  • \n
  • \\PS或者\\PSymbol: 数学符号、货币符号、装饰符号、方框图字符等\n
      \n
    • \\PSm或者\\PMath_Symbol:任何数学符号。
    • \n
    • \\PSc或者\\PCurrency_Symbol:任何货币符号。
    • \n
    • \\PSk或者\\PModifier_Symbol:组合字符(标记)作为其自身的完整字符。
    • \n
    • \\PSo或者\\POther_Symbol:不是数学符号、货币符号或组合字符的各种符号。
    • \n
    \n
  • \n
  • \\PN或者\\PNumber: 任何脚本中的任何类型的数字字符。\n
      \n
    • \\PNd或者\\PDecimal_Digit_Number:除表意文字之外的任何文字中的数字 0 到 9。
    • \n
    • \\PNl或者\\PLetter_Number:看起来像字母的数字,例如罗马数字。
    • \n
    • \\PNo或者\\POther_Number:上标或下标数字,或非数字 0\xe2\x80\x939 的数字(不包括表意文字的数字)。
    • \n
    \n
  • \n
  • \\PP\\PPunctuation: 任何类型的标点字符。\n
      \n
    • \\PPd\\PDash_Punctuation:任何类型的连字符或破折号。
    • \n
    • \\PPs\\POpen_Punctuation:任何类型的左括号。
    • \n
    • \\PPe\\PClose_Punctuation:任何类型的右括号。
    • \n
    • \\PPi\\PInitial_Punctuation:任何类型的开场白。
    • \n
    • \\PPf\\PFinal_Punctuation:任何类型的结束报价。
    • \n
    • \\PPc\\PConnector_Punctuation:标点符号,例如连接单词的下划线。
    • \n
    • \\PPo\\POther_Punctuation:除破折号、括号、引号或连接符之外的任何类型的标点字符。
    • \n
    \n
  • \n
  • \\PC\\POther: 不可见的控制字符和未使用的代码点。\n
      \n
    • \\PCc\\PControl:ASCII 或 Latin-1 控制字符:0x00\xe2\x80\x930x1F 和 0x7F\xe2\x80\x930x9F。
    • \n
    • \\PCf\\PFormat:不可见的格式指示器。
    • \n
    • \\PCo\\PPrivate_Use:保留供私人使用的任何代码点。
    • \n
    • \\PCsor \\PSurrogate:UTF-16 编码中代理对的一半。
    • \n
    • \\PCn\\PUnassigned:未分配字符的任何代码点。
    • \n
    \n
  • \n
\n


小智 5

为了保持控制字符但使它们与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
);
Run Code Online (Sandbox Code Playgroud)

(JSON规则声明:"除了必须转义的字符外,所有Unicode字符都可以放在引号内:引号,反向固定和控制字符(U + 0000到U + 001F).")