我怎样才能从 PHP 字符串中删除像 STX 这样的控制字符
preg_replace("/[^a-zA-Z0-9 .\-_;!:?äÄöÖüÜß<>='\"]/","",$pString)
但是发现它删除的方式太多了。有没有办法只删除 < em > 控制字符?
PHP 确实支持 POSIX-Class,因此您可以使用 [:cntrl:]而不是一些花哨的字符-魔术-东西:
[:cntrl:]
ereg_replace("[:cntrl:]", "", $pString);
编辑:
在5.3中可能需要额外的一对方括号。
ereg_replace("[[:cntrl:]]", "", $pString);
如果你所说的控制字符是指 前32个字符和 \x7F(包括回车符等) ,那么这样就可以了:
\x7F
preg_replace('/[\x00-\x1F\x7F]/', '', $input);
(注意单引号: 使用双引号时,\x00的使用会以某种方式导致解析错误。)
\x00
行馈送和回车(通常写为 \r和 \n)可以像下面这样保存:
\r
\n
preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/', '', $input);
我必须说,我认为 鲍比的回答更好,在这个意义上,[:cntrl:]比 [\x00-\x1F\x7F]更好地传达代码的功能。
[\x00-\x1F\x7F]
警告: ereg_replace在 PHP > = 5.3.0中被弃用,在 PHP > = 7.0.0中被删除! 请使用 preg_replace而不是 ereg_replace:
ereg_replace
preg_replace
preg_replace('/[[:cntrl:]]/', '', $input);
如果你只是想杀死我熟悉的控制字符(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);
为了保留控件字符,但使它们与 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 规则声明: “除了必须转义的字符,所有 Unicode 字符都可以放在引号内: 引号、反向实线和控制字符(U + 0000到 U + 001F)。”)
对于 Unicode 输入,这将从输入文本中删除所有控制字符、未分配的、私有使用的、格式化和代理代码点(这些代码点也不是空格字符,如制表符、新行)。我使用它来从输入中删除所有不可打印的字符。
<?php $clean = preg_replace('/[^\PC\s]/u', '', $input);
有关 \p{C}的详细信息,请参阅 http://www.regular-expressions.info/unicode.html#category
\p{C}
用这个正则..。
/[^\PCc^\PCn^\PCs]/u
像这样..。
$text = preg_replace('/[^\PCc^\PCn^\PCs]/u', '', $text);
^\PCc
^\PCn
^\PCs
简单演示: IDEOne Demo
$text = "\u{0019}hello"; print($text . "\n\n"); $text = preg_replace('/[^\PCc^\PCn^\PCs]/u', '', $text); print($text);
产出:
(-Broken-Character)hello hello
^\PC
^\PCc^\PCn
^\PCc^\PCn^\PCs
^\PCc^\PCn^\PCs^\PCf
看一下可用于在正则表达式中进行测试的 Unicode字符。您应该能够在 微软.NET、 JavaScript、 巨蟒、 爪哇咖啡、 PHP、 露比、 Perl、 戈兰甚至 Adobe中使用这些正则表达式。了解 Unicode字符是 微软.NET0,所以我推荐使用它!
这个正则表达式将匹配任何可见的东西,无论是短手形式还是长手形式..。
\PL\PM\PN\PP\PS\PZ \PLetter\PMark\PNumber\PPunctuation\PSymbol\PSeparator
通常,\p表示它是我们想要匹配的,我们使用 \P(大写) 指示与 < em > 不匹配的内容。 ,但 PHP 没有这个功能,所以我们需要在正则表达式中使用 ^来进行手动否定。
\p
\P
^
一个更简单的正则表达式是 ^\PC,但是这在删除不可见格式方面可能限制太多。你可能想仔细观察,看看什么是最好的,但其中一个选择应该适合你的需要。
如果你想知道任何其他字符集可用,检查 Regular-expressions.info..。
\PL
\PLetter
\PLl
\PLowercase_Letter
\PLu
\PUppercase_Letter
\PLt
\PTitlecase_Letter
\PL&
\PCased_Letter
\PLm
\PModifier_Letter
\PLo
\POther_Letter
\PM
\PMark
\PMn
\PNon_Spacing_Mark
\PMc
\PSpacing_Combining_Mark
\PMe
\PEnclosing_Mark
\PZ
\PSeparator
\PZl
\PLine_Separator
\PZp
\PParagraph_Separator
\PS
\PSymbol
\PSm
\PMath_Symbol
\PSc
\PCurrency_Symbol
\PModifier_Symbol
\PSo
\POther_Symbol
\PN
\PNumber
\PNd
\PDecimal_Digit_Number
\PNl
\PLetter_Number
\PNo
\POther_Number
\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
\PCf
\PFormat
\PCo
\PPrivate_Use
\PCs
\PSurrogate
\PCn
\PUnassigned