如何清理字符串,使其仅包含可打印的ASCII字符?

2024-10-02 18:21:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我想要一个函数来清理字符串。消毒器返回的字符串应该只包含ASCII字符32(空格字符)到ASCII字符126(“~”)。你知道吗

ASCII字符#9(制表符)将替换为四个空格。所有其他非法字符将替换为空字符串。例如,“\n”将替换为空字符串。我们不希望用表示相关转义序列的字符串替换非法字符。例如,我们不希望换行符被反斜杠字符和“n”字符替换。你知道吗

如果最后一个字符串是Unicode编码的,而不是ASCII编码的,就可以了。我只希望允许的字符如下:

" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"

用法示例:

unsafe_string = "\u2502\u251cAPPLES\n\t\t\t\t\t\r\r AND \n\nBANANAS"
safe_string = sanitize(unsafe_string)
print(safe_string)

输出:

APPLES                     AND BANANAS   

编辑:

以下尝试的解决方案不起作用,因为它们无法过滤出新行字符。你知道吗

import string
import re

unsafe_string = "\u2502\u251cAPPLES\n\t\t\t\t\t\r\r AND \n\nBANANAS"

safe_string = re.sub(r'[^\x00-\x7f]',r'', unsafe_string) 
print(safe_string)    

printable = set(string.printable)
safe_string = ''.join(filter(lambda x: x in printable, unsafe_string))
print(safe_string)

Tags: and字符串import编码stringascii字符safe
2条回答

您可以对字符进行迭代,获取代码点,并检查允许的值:

def sanitize(unsafe_str): 
    allowed_range = set(range(32, 127)) 
    safe_str = '' 
    for char in unsafe_str: 
        cp = ord(char) 
        if cp in allowed_range: 
            safe_str += char 
        elif cp == 9: 
            safe_str += ' ' * 4 
    return re.sub(r'\s+', ' ', safe_str) 

示例:

In [1042]: unsafe_string = "\u2502\u251cAPPLES\n\t\t\t\t\t\r\r AND \n\nBANANAS"                                                                                                                             

In [1043]: def sanitize(unsafe_str): 
      ...:     allowed_range = set(range(32, 127)) 
      ...:     safe_str = '' 
      ...:     for char in unsafe_str: 
      ...:         cp = ord(char) 
      ...:         if cp in allowed_range: 
      ...:             safe_str += char 
      ...:         elif cp == 9: 
      ...:             safe_str += ' ' * 4 
      ...:     return re.sub(r'\s+', ' ', safe_str) 
      ...:      
      ...:                                                                                                                                                                                                  

In [1044]: sanitize(unsafe_string)                                                                                                                                                                          
Out[1044]: 'APPLES AND BANANAS'

最后一个re.sub(r'\s+', ' ', safe_str)块是将空白压缩为1。如果您不想这样做,只需执行return safe_str

In [1046]: def sanitize(unsafe_str): 
      ...:     allowed_range = set(range(32, 127)) 
      ...:     safe_str = '' 
      ...:     for char in unsafe_str: 
      ...:         cp = ord(char) 
      ...:         if cp in allowed_range: 
      ...:             safe_str += char 
      ...:         elif cp == 9: 
      ...:             safe_str += ' ' * 4 
      ...:     return safe_str 
      ...:                                                                                                                                                                                                     

In [1047]: sanitize(unsafe_string)                                                                                                                                                                          
Out[1047]: 'APPLES                     AND BANANAS'

FWIW,这会在每次运行函数时生成允许的列表,但由于它是一个常量,您可以将它放在模块级别,以便只生成一次,例如:

ALLOWED_RANGE = set(range(32, 127)) 
import re

def sanitize(s):
    s = s.replace("\t", "    ")
    return re.sub(r"[^ -~]", "", s)

[ -~]表示“在 (space) to ~范围内的所有事物”。在开头加上^意味着除此之外的一切。你知道吗

输出为:

APPLES                     AND BANANAS

在示例输出中,忘记了用空格替换制表符。你知道吗

相关问题 更多 >