当前位置: 首页 > 知识库问答 >
问题:

如何删除字符串中所有不可打印的字符?

彭高畅
2023-03-14

我想我需要删除字符0-31和127。

是否有一个函数或一段代码来高效地做到这一点?

共有2个答案

徐昕
2023-03-14

这里的许多其他答案都没有考虑到unicode字符(例如:öäüsdoinweiwoujuhu)。在这种情况下,您可以使用以下方法

$string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/u', '', $string);

\x80-\x9f范围内(刚好高于7位ASCII字符范围)有一类奇怪的字符,它们在技术上是控制字符,但随着时间的推移,它们被误用为可打印字符。如果您对这些没有任何问题,那么您可以使用:

$string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/u', '', $string);

如果您还希望去掉换行符、回车符、制表符、非分隔空格和软连字符,可以使用:

$string = preg_replace('/[\x00-\x1F\x7F-\xA0\xAD]/u', '', $string);

注意,对于上面的示例,您必须使用单引号。

如果您希望删除除基本可打印ASCII字符外的所有字符(上面的所有示例字符都将被删除),您可以使用:

$string = preg_replace( '/[^[:print:]]/', '',$string);

参见http://www.fileformat.info/info/charset/utf-8/list.htm

饶滨海
2023-03-14

如果您的Tardis是在1963年登陆的,您只想要7位可打印的ASCII字符,那么您可以通过以下操作删除0-31和127-255之间的所有内容:

$string = preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $string);

它匹配范围0-31、127-255中的任何内容并将其删除。

你掉进了热水浴缸时光机,你又回到了八十年代。如果您有某种形式的8位ASCII,那么您可能希望将字符保持在128-255的范围内。一个简单的调整-只需寻找0-31和127

$string = preg_replace('/[\x00-\x1F\x7F]/', '', $string);

啊,欢迎回到21世纪。如果您有一个UTF-8编码的字符串,那么可以在regex上使用/u修饰符

$string = preg_replace('/[\x00-\x1F\x7F]/u', '', $string);

这只是删除了0-31和127。这在ASCII和UTF-8中工作,因为两者共享相同的控制集范围(如下文mgutt所述)。严格地说,这可以在没有/u修饰符的情况下工作。但如果你想清除其他的焦碳,这会让你的生活变得更轻松...

如果您正在处理Unicode,可能会有许多非打印元素,但让我们考虑一个简单的元素:无中断空格(u+00a0)

在UTF-8字符串中,这将被编码为0xC2A0。您可以查找并删除该特定序列,但使用/u修饰符后,只需将\xa0添加到character类:

$string = preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $string);

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);

从直觉上看,这似乎很快,但并不总是这样,您应该确定基准测试,看看它是否为您节省了什么。我使用随机数据对各种字符串长度进行了一些基准测试,使用PHP7.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有一个边缘。

我认为这是一个有趣的结果,所以包括在这里。重要的不是拿着这个结果,用它来决定使用哪种方法,而是对照自己的数据进行基准测试,然后再决定。

 类似资料:
  • 问题内容: 我想我需要删除0-31和127字符, 是否有功能或一段代码可以有效地做到这一点。 问题答案: 7位ASCII? 如果您的Tardis刚好在1963年登陆,并且您只想要7位可打印的ASCII字符,则可以使用以下方法从0-31和127-255中删除所有内容: 它匹配0-31、127-255范围内的任何内容并将其删除。 8位扩展ASCII? 您掉进了热水浴缸计时机,而您又回到了八十年代。如果

  • 问题内容: 我得到的用户输入包括非ASCII字符和不可打印的字符,例如 例如: 所需的输出: 使用Java删除它们的最佳方法是什么? 我尝试了以下操作,但似乎不起作用 输出量 问题答案: 您的要求不清楚。Java 中的所有字符都是Unicode字符,因此,如果将其删除,将留下一个空字符串。我假设您的意思是您要删除任何非ASCII,不可打印的字符。 此处, 代表可打印ASCII字符的POSIX字符类

  • 使用getID3,有时标签中有特殊字符(带问号的小黑钻),但我似乎无法删除它们 我尝试了这里的一切 PHP:如何删除字符串中所有不可打印的字符? 在数据库(phpMyAdmin)中,当打印出来时,它们显示为??在数据的开头。 问题是,我根本不希望这些字符出现在数据库中(无论它们是否正确显示或显示为问号) 但是,我尝试过的所有代码都不会删除PHP中的这些特殊字符

  • 问题内容: 我在textarea中有一个文本,我使用.value属性将其读出。 现在,我想使用正则表达式.replace从我的文本中删除所有换行符(按时产生的字符),但是如何在正则表达式中指示换行符? 如果那不可能,还有另一种方法吗? 问题答案: 这可能是一个常见问题解答。无论如何,换行符(更好的是:换行符)可以是回车符(在较旧的Mac上为CR,),换行符(在Unices 包括Linux上为LF,

  • 我在textarea中有一个文本,我使用.value属性读出它。 现在我想从我的文本中删除所有的换行符(按Enter时产生的字符),现在使用.替换为正则表达式,但如何在正则表达式中指示换行符? 如果不可能的话,是否还有其他方法?

  • 我应该编写一个函数,排除句子(字符串)中的某些字母(char)。我基本上也这么做了,但问题是我只剪掉了这个字母在句子中的第一次出现。 我需要如何更改最后一个函数以删除字母的所有外观?找到所有索引可能并不难,但真正的困难是之后将子字符串放在一起,这样您仍然只剩下一句话,而没有某些字母。因为如果我理解正确,索引越多,您需要添加的不同子字符串就越多。 目前我得到了这个。 我们的目标是: