如何从字符串列表中去除所有转义序列?

23 投票
6 回答
106490 浏览
提问于 2025-04-17 06:15

我想从一组字符串中去掉所有类型的转义序列。我该怎么做呢?

['william', 'short', '\x80', 'twitter', '\xaa', '\xe2', 'video', 'guy', 'ray']

输出:

['william', 'short', 'twitter', 'video', 'guy', 'ray']

http://docs.python.org/reference/lexical_analysis.html#string-literals

6 个回答

4

你可以使用列表推导式和 str.isalnum() 来过滤掉那些不是字母或数字的“单词”。

>>> l = ['william', 'short', '\x80', 'twitter', '\xaa', '\xe2', 'video', 'guy', 'ray']
>>> [word for word in l if word.isalnum()]
['william', 'short', 'twitter', 'video', 'guy', 'ray']

如果你还想过滤掉数字,那就可以用 str.isalpha() 来代替:

>>> l = ['william', 'short', '\x80', 'twitter', '\xaa', '\xe2', 'video', 'guy', 'ray', '456']
>>> [word for word in l if word.isalpha()]
['william', 'short', 'twitter', 'video', 'guy', 'ray']
42

如果你想去掉一些你不喜欢的字符,可以使用translate这个函数来把它们去掉:

>>> s="\x01\x02\x10\x13\x20\x21hello world"
>>> print(s)
 !hello world
>>> s
'\x01\x02\x10\x13 !hello world'
>>> escapes = ''.join([chr(char) for char in range(1, 32)])
>>> t = s.translate(None, escapes)
>>> t
' !hello world'

这个方法会去掉所有这些控制字符:

   001   1     01    SOH (start of heading)
   002   2     02    STX (start of text)
   003   3     03    ETX (end of text)
   004   4     04    EOT (end of transmission)
   005   5     05    ENQ (enquiry)
   006   6     06    ACK (acknowledge)
   007   7     07    BEL '\a' (bell)
   010   8     08    BS  '\b' (backspace)
   011   9     09    HT  '\t' (horizontal tab)
   012   10    0A    LF  '\n' (new line)
   013   11    0B    VT  '\v' (vertical tab)
   014   12    0C    FF  '\f' (form feed)
   015   13    0D    CR  '\r' (carriage ret)
   016   14    0E    SO  (shift out)
   017   15    0F    SI  (shift in)
   020   16    10    DLE (data link escape)
   021   17    11    DC1 (device control 1)
   022   18    12    DC2 (device control 2)
   023   19    13    DC3 (device control 3)
   024   20    14    DC4 (device control 4)
   025   21    15    NAK (negative ack.)
   026   22    16    SYN (synchronous idle)
   027   23    17    ETB (end of trans. blk)
   030   24    18    CAN (cancel)
   031   25    19    EM  (end of medium)
   032   26    1A    SUB (substitute)
   033   27    1B    ESC (escape)
   034   28    1C    FS  (file separator)
   035   29    1D    GS  (group separator)
   036   30    1E    RS  (record separator)
   037   31    1F    US  (unit separator)

对于3.1版本以上的Python,使用的方法会有所不同:

>>> s="\x01\x02\x10\x13\x20\x21hello world"
>>> print(s)
 !hello world
>>> s
'\x01\x02\x10\x13 !hello world'
>>> escapes = ''.join([chr(char) for char in range(1, 32)])
>>> translator = str.maketrans('', '', escapes)
>>> t = s.translate(translator)
>>> t
' !hello world'
19

像这样吗?

>>> from ast import literal_eval
>>> s = r'Hello,\nworld!'
>>> print(literal_eval("'%s'" % s))
Hello,
world!

编辑: 好吧,这不是你想要的。你想要的事情一般是做不到的,因为正如 @Sven Marnach 解释的,字符串实际上并不包含转义序列。那些只是字符串字面量中的一种表示方式。

你可以用下面的代码从你的列表中过滤掉所有包含非ASCII字符的字符串:

def is_ascii(s):
    try:
        s.decode('ascii')
        return True
    except UnicodeDecodeError:
        return False

[s for s in ['william', 'short', '\x80', 'twitter', '\xaa',
             '\xe2', 'video', 'guy', 'ray']
 if is_ascii(s)]

撰写回答