【问题标题】:How to remove all the escape sequences from a list of strings?如何从字符串列表中删除所有转义序列?
【发布时间】:2011-11-13 22:28:35
【问题描述】:

我想从字符串列表中删除所有类型的转义序列。我怎样才能做到这一点? 输入:

['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

【问题讨论】:

  • 最终的字符串对象不携带任何关于构造它的字符串文字是否包含转义序列的信息。如果你连是否有都分不清,你会如何“删除”它们?

标签: python


【解决方案1】:

如果你想去除一些你不喜欢的字符,你可以使用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'

【讨论】:

  • 抱歉,这个循环让我感到畏缩。 escapes = ''.join([chr(char) for char in range(1, 32)])s.translate(None, escapes)
  • @AdamGriffiths,这是一个不错的改变。谢谢。
  • 我喜欢这个答案而不是第一个。它运行良好且非常灵活。
  • 这个答案有点过时了。在 Python 3.1 及更高版本中,您需要在声明 escapes 之后添加这两行。 translator = str.maketrans('', '', escapes) 然后t = s.translate(translator)
  • @yvihs,感谢您的修复!我已经为较新的 python 编辑了我的答案。
【解决方案2】:

这样的?

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

【讨论】:

    【解决方案3】:

    您可以使用列表理解和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']
    

    【讨论】:

    • 这对于许多应用程序来说是一个很好的答案,尽管应该注意其他非字母数字字符(如空格)也会受到影响。
    【解决方案4】:

    至少在您所要求的广泛范围内,这是无法做到的。正如其他人所提到的,运行时 python 不知道有转义序列的东西和没有转义序列的东西之间的区别。

    例子:

    print ('\x61' == 'a')
    

    打印True。所以没有办法找到这两个字符串之间的区别,除非你尝试对你的 python 脚本进行一些静态分析。

    【讨论】:

      【解决方案5】:

      以下在 Python 3.6 中对我有用:

      word = '\t\t\t\t\t\ntest\t msg'
      filter = ''.join([chr(i) for i in range(1, 32)])
      word.translate(str.maketrans('', '', filter))
      

      输出:

      'test msg'
      

      来源here

      【讨论】:

      • 非常适合我!
      【解决方案6】:

      我在从十六进制转换为字符串时遇到了类似的问题。这最终在 python 中起作用了 示例

      list_l = ['william', 'short', '\x80', 'twitter', '\xaa', '\xe2', 'video', 'guy', 'ray']
      decode_data=[]
      for l in list_l:
          data =l.decode('ascii', 'ignore')
          if data != "":
              decode_data.append(data)
      
      # output :[u'william', u'short', u'twitter', u'video', u'guy', u'ray']
      

      【讨论】:

        猜你喜欢
        • 2020-10-07
        • 1970-01-01
        • 2011-11-02
        • 2013-01-19
        • 1970-01-01
        • 2019-02-12
        相关资源
        最近更新 更多