【问题标题】:How to remove \xa0 from string in Python?如何从 Python 中的字符串中删除 \xa0?
【发布时间】:2012-06-15 03:43:49
【问题描述】:

我目前正在使用 Beautiful Soup 解析 HTML 文件并调用 get_text(),但似乎我留下了很多 \xa0 Unicode 表示空格。有没有一种有效的方法可以在 Python 2.7 中删除所有这些,并将它们更改为空格?我想更笼统的问题是,有没有办法删除 Unicode 格式?

我尝试使用:line = line.replace(u'\xa0',' '),正如另一个线程所建议的那样,但这将 \xa0 更改为 u,所以现在我到处都有“u”。 ):

编辑:问题似乎已由str.replace(u'\xa0', ' ').encode('utf-8') 解决,但只是在没有replace() 的情况下执行.encode('utf-8') 似乎会导致它吐出更奇怪的字符,例如\xc2。谁能解释一下?

【问题讨论】:

  • 已经试过了,'ascii' 编解码器无法解码位置 0 的字节 0xa0:序数不在范围内(128)
  • 拥抱 Unicode。使用u''s 而不是''s。 :-)
  • 尝试使用 str.replace(u'\xa0', ' ') 但到处都是“u”而不是 \xa0s :/
  • 如果字符串是 unicode 字符串,则必须使用 u' ' 替换,而不是 ' '。原始字符串是 unicode 的吗?

标签: python python-2.7 unicode beautifulsoup utf-8


【解决方案1】:

你可以试试string.strip()
它对我有用! :)

【讨论】:

    【解决方案2】:

    \xa0 实际上是 Latin1 (ISO 8859-1) 中的不间断空格,也是 chr(160)。您应该用空格替换它。

    string = string.replace(u'\xa0', u' ')

    .encode('utf-8') 时,它会将 unicode 编码为 utf-8,这意味着每个 unicode 可以用 1 到 4 个字节表示。对于这种情况,\xa0 由 2 个字节 \xc2\xa0 表示。

    阅读http://docs.python.org/howto/unicode.html

    请注意:这个答案从 2012 年开始,Python 已经继续,您现在应该可以使用 unicodedata.normalize

    【讨论】:

    • 我对 Unicode 和字符编码了解不多。但似乎unicodedata.normalize 比 str.replace 更合适
    • 您对字符串的建议是可行的,但请注意,所有对该字符串的引用也需要替换。例如,如果您有一个打开文件的程序,并且其中一个文件的名称中有一个不间断的空格,则除了执行此替换之外,您还需要重命名该文件。跨度>
    • U+00a0 is a non-breakable space Unicode character 在 latin1 编码中可以编码为 b'\xa0' 字节,在 utf-8 编码中可以编码为两个字节 b'\xc2\xa0'。在html中可以表示为 
    • 当我尝试这个时,我得到UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 397: ordinal not in range(128)
    • 我在一个字符串列表上尝试了这段代码,它没有做任何事情,并且 \xa0 字符仍然存在。如果我将我的文本文件重新编码为 UTF-8,该字符将显示为一个大写字母 A,其头部带有一个胡萝卜,而我将其编码为 Unicode,Python 解释器崩溃了。
    【解决方案3】:

    Python 将其识别为空格字符,因此您可以在不使用 args 的情况下 split 它并通过普通空格连接:

    line = ' '.join(line.split())
    

    【讨论】:

      【解决方案4】:

      它相当于一个空格字符,所以去掉它

      print(string.strip()) # no more xa0
      

      【讨论】:

      • 这只会在它位于字符串的开头或结尾时将其删除。
      【解决方案5】:

      带有正则表达式的通用版本(它将删除所有控制字符):

      import re
      def remove_control_chart(s):
          return re.sub(r'\\x..', '', s)
      

      【讨论】:

        【解决方案6】:

        在尝试了几种方法后,总结一下,我就是这样做的。以下是从解析的 HTML 字符串中避免/删除 \xa0 字符的两种方法。

        假设我们的原始 html 如下:

        raw_html = '<p>Dear Parent, </p><p><span style="font-size: 1rem;">This is a test message, </span><span style="font-size: 1rem;">kindly ignore it. </span></p><p><span style="font-size: 1rem;">Thanks</span></p>'
        

        让我们尝试清理这个 HTML 字符串:

        from bs4 import BeautifulSoup
        raw_html = '<p>Dear Parent, </p><p><span style="font-size: 1rem;">This is a test message, </span><span style="font-size: 1rem;">kindly ignore it. </span></p><p><span style="font-size: 1rem;">Thanks</span></p>'
        text_string = BeautifulSoup(raw_html, "lxml").text
        print text_string
        #u'Dear Parent,\xa0This is a test message,\xa0kindly ignore it.\xa0Thanks'
        

        以上代码在字符串中生成这些字符\xa0。要正确删除它们,我们可以使用两种方法。

        方法#1(推荐): 第一个是 BeautifulSoup 的 get_text 方法,其中 strip 参数为 True 所以我们的代码变成了:

        clean_text = BeautifulSoup(raw_html, "lxml").get_text(strip=True)
        print clean_text
        # Dear Parent,This is a test message,kindly ignore it.Thanks
        

        方法#2: 另一种选择是使用python的库unicodedata

        import unicodedata
        text_string = BeautifulSoup(raw_html, "lxml").text
        clean_text = unicodedata.normalize("NFKD",text_string)
        print clean_text
        # u'Dear Parent,This is a test message,kindly ignore it.Thanks'
        

        我还详细介绍了这些方法on this blog,您可能想参考一下。

        【讨论】:

        • get_text(strip=True) 确实起到了作用。谢谢 m8
        【解决方案7】:

        试试这个代码

        import re
        re.sub(r'[^\x00-\x7F]+','','paste your string here').decode('utf-8','ignore').strip()
        

        【讨论】:

          【解决方案8】:

          Python 的unicodedata 库中有很多有用的东西。其中之一是.normalize() 函数。

          试试:

          new_str = unicodedata.normalize("NFKD", unicode_str)
          

          如果您没有得到想要的结果,请使用上面链接中列出的任何其他方法替换 NFKD。

          【讨论】:

          • 不太确定,您可能希望 normalize('NFKD', '1º\xa0dia') 返回 '1º dia' 但它返回 '1o dia'
          • 啊,如果文字是“韩语”,请不要尝试这个。 글자가 전부 깨져버리네요.
          • 此解决方案将俄罗斯字母 й 更改为两个 unicode 字符的外观相同的序列。这里的问题是过去相等的字符串不再匹配。修复:使用"NFKC" 而不是"NFKD"
          • 这太棒了。它将单字母字符串 更改为实际的四字母字符串 ریال。因此,在需要时更换要容易得多。你会标准化然后替换,而不必关心它是哪一个。 normalize("NFKD", "﷼").replace("ریال", '').
          【解决方案9】:

          尝试在行尾使用 .strip() line.strip() 对我来说效果很好

          【讨论】:

            【解决方案10】:

            我在谷歌上搜索不可打印字符的问题时最终来到了这里。我使用 MySQL UTF-8 general_ci 并处理波兰语。对于有问题的字符串,我必须按如下方式处理:

            text=text.replace('\xc2\xa0', ' ')
            

            这只是一种快速的解决方法,您可能应该尝试使用正确的编码设置。

            【讨论】:

            • 如果text 是一个表示使用 utf-8 编码的文本的字节串,则此方法有效。如果您正在处理文本;首先将其解码为 Unicode (.decode('utf-8')),然后仅在最后将其编码为字节串(如果 API 不直接支持 Unicode,例如 socket)。对文本的所有中间操作都应该在 Unicode 上执行。
            【解决方案11】:

            在Beautiful Soup 中,您可以传递get_text() 的strip 参数,该参数从文本的开头和结尾去除空白。如果 \xa0 或任何其他空格出现在字符串的开头或结尾,这将删除它。 Beautiful Soup 用 \xa0 替换了一个空字符串,这为我解决了问题。

            mytext = soup.get_text(strip=True)
            

            【讨论】:

            • strip=True 仅在 &amp;nbsp; 位于每一位文本的开头或结尾时才有效。如果它在文本中的其他字符之间,它不会删除空格。
            【解决方案12】:

            我在使用 python 从 sqlite3 数据库中提取一些数据时遇到了同样的问题。上面的答案对我不起作用(不知道为什么),但确实如此:line = line.decode('ascii', 'ignore') 但是,我的目标是删除 \xa0s,而不是用空格替换它们。

            我从this super-helpful unicode tutorial by Ned Batchelder.得到这个

            【讨论】:

            • 您现在正在删除任何不是 ASCII 字符的内容,您可能正在掩盖您的实际问题。即使您不了解离合器的工作原理,使用'ignore' 就像推过换档杆一样......
            • @MartijnPieters 链接的 unicode 教程很好,但您是完全正确的 - str.encode(..., 'ignore')try: ... except: ... 的 Unicode 处理等价物。虽然它可能会隐藏错误消息,但它很少能解决问题。
            • 对于某些目的,例如处理 EMAIL 或 URLS,使用 .decode('ascii', 'ignore') 似乎很完美
            • samwize's answer 不适用于您,因为它适用于 Unicode 字符串。 line.decode() 在你的回答中暗示你的输入是一个 bytestring (你不应该在 Unicode 字符串上调用 .decode() (为了强制它,该方法在 Python 3 中被删除)。我不了解如何可以看到 the tutorial that you've linked in your answer 并忽略字节和 Unicode 之间的区别(不要混合它们)。
            【解决方案13】:

            0xA0 (Unicode) 在 UTF-8 中是 0xC2A0。 .encode('utf8') 只会使用您的 Unicode 0xA0 并替换为 UTF-8 的 0xC2A0。因此 0xC2s 的出现......编码并没有取代,正如您现在可能已经意识到的那样。

            【讨论】:

            • 0xc2a0 不明确(字节顺序)。请改用 b'\xc2\xa0' 字节文字。
            【解决方案14】:

            试试这个:

            string.replace('\\xa0', ' ')
            

            【讨论】:

            • @RyanMartin:这替换了 四个字节len(b'\\xa0') == 4len(b'\xa0') == 1。如果可能的话;您应该修复产生这些转义的上游。
            • 这个解决方案对我有用:string.replace('\xa0', ' ')
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-04-16
            • 1970-01-01
            • 2020-03-22
            • 2020-10-07
            相关资源
            最近更新 更多