7 位 ASCII?
如果您的 Tardis 于 1963 年刚刚上市,并且您只想要 7 位可打印 ASCII 字符,则可以使用以下命令删除 0-31 和 127-255 之间的所有内容:
$string = preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $string);
它匹配 0-31、127-255 范围内的任何内容并将其删除。
8 位扩展 ASCII?
你掉进了热水浴缸时间机器,然后你又回到了八十年代。
如果您有某种形式的 8 位 ASCII,那么您可能希望将字符保持在 128-255 范围内。调整简单 - 只需查找 0-31 和 127
$string = preg_replace('/[\x00-\x1F\x7F]/', '', $string);
UTF-8?
啊,欢迎回到21世纪。如果您有 UTF-8 编码的字符串,那么/u
modifier http://php.net/manual/en/reference.pcre.pattern.modifiers.php可以在正则表达式上使用
$string = preg_replace('/[\x00-\x1F\x7F]/u', '', $string);
这只是删除了 0-31 和 127。这适用于 ASCII 和 UTF-8,因为两者共享相同的控制设定范围 http://www.fileformat.info/info/charset/UTF-8/list.htm(正如下面 mgutt 所指出的)。严格来说,这无需/u
修饰符。但如果你想删除其他字符,它会让生活变得更容易......
如果您正在处理 Unicode,那么有潜在的许多非打印元素 https://stackoverflow.com/questions/3770117/what-is-the-range-of-unicode-printable-characters,但让我们考虑一个简单的:不间断空格 (U+00A0) https://unicode-table.com/en/00A0/
在 UTF-8 字符串中,这将被编码为0xC2A0
。您可以查找并删除该特定序列,但使用/u
修饰符到位,您可以简单地添加\xA0
到字符类:
$string = preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $string);
附录:str_replace 怎么样?
preg_replace 非常高效,但是如果您经常执行此操作,您可以构建一个要删除的字符数组,并使用 str_replace,如下 mgutt 所示,例如
//build an array we can re-use across several operations
$badchar=array(
// control characters
chr(0), chr(1), chr(2), chr(3), chr(4), chr(5), chr(6), chr(7), chr(8), chr(9), chr(10),
chr(11), chr(12), chr(13), chr(14), chr(15), chr(16), chr(17), chr(18), chr(19), chr(20),
chr(21), chr(22), chr(23), chr(24), chr(25), chr(26), chr(27), chr(28), chr(29), chr(30),
chr(31),
// non-printing characters
chr(127)
);
//replace the unwanted chars
$str2 = str_replace($badchar, '', $str);
直观上,这似乎会很快,但情况并非总是如此,您绝对应该进行基准测试,看看它是否可以为您节省任何东西。我使用随机数据对各种字符串长度进行了一些基准测试,并且使用 php 7.0.12 出现了这种模式
2 chars str_replace 5.3439ms preg_replace 2.9919ms preg_replace is 44.01% faster
4 chars str_replace 6.0701ms preg_replace 1.4119ms preg_replace is 76.74% faster
8 chars str_replace 5.8119ms preg_replace 2.0721ms preg_replace is 64.35% faster
16 chars str_replace 6.0401ms preg_replace 2.1980ms preg_replace is 63.61% faster
32 chars str_replace 6.0320ms preg_replace 2.6770ms preg_replace is 55.62% faster
64 chars str_replace 7.4198ms preg_replace 4.4160ms preg_replace is 40.48% faster
128 chars str_replace 12.7239ms preg_replace 7.5412ms preg_replace is 40.73% faster
256 chars str_replace 19.8820ms preg_replace 17.1330ms preg_replace is 13.83% faster
512 chars str_replace 34.3399ms preg_replace 34.0221ms preg_replace is 0.93% faster
1024 chars str_replace 57.1141ms preg_replace 67.0300ms str_replace is 14.79% faster
2048 chars str_replace 94.7111ms preg_replace 123.3189ms str_replace is 23.20% faster
4096 chars str_replace 227.7029ms preg_replace 258.3771ms str_replace is 11.87% faster
8192 chars str_replace 506.3410ms preg_replace 555.6269ms str_replace is 8.87% faster
16384 chars str_replace 1116.8811ms preg_replace 1098.0589ms preg_replace is 1.69% faster
32768 chars str_replace 2299.3128ms preg_replace 2222.8632ms preg_replace is 3.32% faster
时间本身是针对 10000 次迭代的,但更有趣的是相对差异。最多 512 个字符,我发现 preg_replace 总是获胜。在 1-8kb 范围内,str_replace 有一定的优势。
我认为这是一个有趣的结果,所以将其放在这里。重要的不是获取这个结果并用它来决定使用哪种方法,而是根据自己的数据进行基准测试,然后做出决定。