python - 带有特殊字符的字符串不适用于 Python 和正则表达式

标签 python regex

我正在参与这个项目,其中的特殊角色让我发疯!我在论坛上搜索了很多解决方案,但都没有解决我的问题。

我有这个带有特殊字符的字符串:

['{"response":{"startRow":0,"endRow":5,"totalRows":5,"data":   [{"CODIGO":"72","DESCRICAO":"RECEITA INTRA-ORÇÁMENTÁRIAS DE CONTRIBUÇÕES","PREVISTA":225847716.0,"REALIZADA":165311075.58,"DIFERENCA":60536640.42,"R___":1.0},{"CODIGO":"76","DESCRICAO":"RECEITA  INTRA-ORÇAMENTÁRIAS DE SERVIÇOS","PREVISTA":22367493.0,"REALIZADA":3435363.08,"DIFERENCA":18932129.92,"R___":2.0},{"CODIGO":"77","DESCRICAO":"TRANSFERÊNCIAS  INTRA-ORÇAMENTÁRIAS CORRENTES","PREVISTA":1218252.0,"REALIZADA":0.0,"DIFERENCA":1218252.0,"R___":3.0},{"CODIGO":"71","DESCRICAO":"RECEITA TRIBUTÁRIA INTRA-ORÇAMENTÁRIA","PREVISTA":12000.0,"REALIZADA":0.0,"DIFERENCA":12000.0,"R___":4.0},{"CODIGO":"79","DESCRICAO":"OUTRAS RECEITAS INTRA-ORÇAMENTÁRIAS CORRENTES","PREVISTA":0.0,"REALIZADA":311785.30,"DIFERENCA":-311785.30,"R___":5.0}]}}']

我必须使用正则表达式找到一些特定的字符串,但我必须保留特殊字符。

我尝试过一些事情:

nkfd_form = unicodedata.normalize('NFKD', unicode(html))
print u"".join([c for c in nkfd_form if not unicodedata.combining(c)])

print ' '.join(re.findall(r'(?:\w{3,}|-(?=\s))', html))
print ' '.join(''.join([i if ord(i) < 128 else ' ' for i in html]).split())

还有很多其他的事情......

但是当我使用我的模式搜索时:

result = re.findall('(:\"[\w\-r"/" ]+"|:[\w\s.\-r"/" ]+)', html, re.U)

特殊字符不正确。结果是这样的:

[':0', ':2', ':2', ':"94"', ':"DEDU', ':0.0', ':-2748373.25', ':2748373.25', ':1.0', ':"95"', ':"DEDU', ':-1421484000.0', ':-1062829156.22', ':-358654843.78', ':2.0']
[':0', ':5', ':5', ':"72"', ':"RECEITA INTRA-OR', ':225847716.0', ':165311075.58', ':60536640.42', ':1.0', ':"76"', ':"RECEITA  INTRA-OR', ':22367493.0', ':3435363.08', ':18932129.92', ':2.0', ':"77"', ':"TRANSFER', ':1218252.0', ':0.0', ':1218252.0', ':3.0', ':"71"', ':"RECEITA TRIBUT', ':12000.0', ':0.0', ':12000.0', ':4.0', ':"79"', ':"OUTRAS RECEITAS INTRA-OR', ':0.0', ':311785.30', ':-311785.30', ':5.0']

它忽略特殊字符!

我需要它,因为我将在 CSV 文件中写入数据,但它无法处理此错误。

使用提示进行简单测试:

>>> import re
>>> re.findall('\w+', 'Márquez', re.U)
['M\xc3', 'rquez']

我需要做什么来解决这个问题?

最佳答案

将我的评论变成答案(有点,因为它不包含正则表达式):

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import json
import csv
import cStringIO
import codecs
import types


class UnicodeDictWriter(csv.DictWriter):
    """
    A CSV DictWriter which will write rows to CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, fields, dialect=csv.excel, encoding="utf-8", **kwds):
        # Redirect output to a queue
        self.queue = cStringIO.StringIO()
        self.writer = csv.DictWriter(
            self.queue, fields, dialect=dialect, **kwds)
        self.stream = f
        self.encoder = codecs.getincrementalencoder(encoding)()

    def writerow(self, row):
        self.writer.writerow(dict(
            (f, v.encode("utf-8") if isinstance(v, types.StringTypes) else v)
                for f, v in row.iteritems()))
        # Fetch UTF-8 output from the queue ...
        data = self.queue.getvalue()
        data = data.decode("utf-8")
        # ... and reencode it into the target encoding
        data = self.encoder.encode(data)
        # write to the target stream
        self.stream.write(data)
        # empty queue
        self.queue.truncate(0)

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)


data = '{"response":{"startRow":0,"endRow":5,"totalRows":5,"data":   [{"CODIGO":"72","DESCRICAO":"RECEITA INTRA-ORÇÁMENTÁRIAS DE CONTRIBUÇÕES","PREVISTA":225847716.0,"REALIZADA":165311075.58,"DIFERENCA":60536640.42,"R___":1.0},{"CODIGO":"76","DESCRICAO":"RECEITA  INTRA-ORÇAMENTÁRIAS DE SERVIÇOS","PREVISTA":22367493.0,"REALIZADA":3435363.08,"DIFERENCA":18932129.92,"R___":2.0},{"CODIGO":"77","DESCRICAO":"TRANSFERÊNCIAS  INTRA-ORÇAMENTÁRIAS CORRENTES","PREVISTA":1218252.0,"REALIZADA":0.0,"DIFERENCA":1218252.0,"R___":3.0},{"CODIGO":"71","DESCRICAO":"RECEITA TRIBUTÁRIA INTRA-ORÇAMENTÁRIA","PREVISTA":12000.0,"REALIZADA":0.0,"DIFERENCA":12000.0,"R___":4.0},{"CODIGO":"79","DESCRICAO":"OUTRAS RECEITAS INTRA-ORÇAMENTÁRIAS CORRENTES","PREVISTA":0.0,"REALIZADA":311785.30,"DIFERENCA":-311785.30,"R___":5.0}]}}'
field_order = [
    'CODIGO', 'DESCRICAO', 'PREVISTA', 'REALIZADA', 'DIFERENCA', 'R___']

with open('jsontest.csv', 'w') as csvfile:
    writer = UnicodeDictWriter(csvfile, field_order)
    writer.writerows(json.loads(data)['response']['data'])

然后 jsontest.csv 看起来像这样:

72,RECEITA INTRA-ORÇÁMENTÁRIAS DE CONTRIBUÇÕES,225847716.0,165311075.58,60536640.42,1.0
76,RECEITA  INTRA-ORÇAMENTÁRIAS DE SERVIÇOS,22367493.0,3435363.08,18932129.92,2.0
77,TRANSFERÊNCIAS  INTRA-ORÇAMENTÁRIAS CORRENTES,1218252.0,0.0,1218252.0,3.0
71,RECEITA TRIBUTÁRIA INTRA-ORÇAMENTÁRIA,12000.0,0.0,12000.0,4.0
79,OUTRAS RECEITAS INTRA-ORÇAMENTÁRIAS CORRENTES,0.0,311785.3,-311785.3,5.0

我使用Python 2.6.8。

顺便说一句:我改编了 here 中的 UnicodeDictWriter 类。只需向下滚动两到三个屏幕,您就会找到原始的 UnicodeWriter 类。

关于python - 带有特殊字符的字符串不适用于 Python 和正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12549414/

相关文章:

c# - 正则表达式回顾(?)。最多只有标识符后面和后面的第一个标签

regex - Bash 脚本解析文件以查找模式之间多次出现的字符串

python - 为什么我的 GPIO 引脚无法使用 RPi.GPIO 正确设置?

python - 如何使用 Python 3.x 成功导入 numpy?

python - 在带 2 个小数的字符串中排序数字的问题

arrays - 基本 perl : regex statement not working in perl 5. 10.1 机器但在 5.18 中工作?

python - 将正则表达式与日期时间一起使用

c++ - 通过 Python 控制台对 PythonQt 库进行非锁定调用

python - Django 和 web.py,用 Python 建大型网站哪个更好?

regex - 发出运行 sed 以替换文件中的字符串