2012-09-23 72 views
0

我在這個項目上工作和特殊字符快把我逼瘋了!我已經在foruns周圍搜索了很多解決方案,但他們沒有解決我的問題。字符串包含特殊字符不使用Python工作,正則表達式

我有這個字符串特殊字符:

['{"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) 

特殊字符AREN沒錯。結果是這樣的:

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

我有什麼做的,解決這一問題?

+3

你的字符串似乎是有效的JSON代碼。那麼爲什麼你把它稱爲「html」(你的變量的名稱)?爲什麼不使用[json模塊](http://docs.python.org/library/json.html)?並且永遠記得[Jamie Zawinski着名的說法](http://regex.info/blog/2006-09-15/247)。 – pillmuncher

+0

讓我們從_simple test_開始(在你的問題中的最後一節):不要在控制檯上輸入,而是要創建py文件,確保它是UTF-8,運行它。它工作嗎? - 它應該工作,如果是這樣,那麼你的控制檯編碼不是unicode。輸入文件也是如此。 –

+1

順便說一句,你使用什麼py版本,2.x或3.x? –

回答

0

您的意見似乎是unicode的,但正則表達式是不是..

嘗試改變ALL您正則表達式模式爲unicode,像這樣:

print ' '.join(re.findall(ur'(?:\w{3,}|-(?=\s))', html)) 

參考:

http://docs.python.org/tutorial/introduction.html#unicode-strings

+0

謝謝你的答案 但它仍然是錯的! 結果是: '響應STARTROWË ndRow totalRows data CODIGO DESCRICAO TRANSFER xc3 x8aNCIAS INTRA xc3 x87AMENT xc3 x81RIAS CAPITAL PREVISTA 5253000 REALIZADA DIFERENCA 5253000 R ___' – Kamilla

1

談到我的意見爲答案(樣的,因爲它不包含正則表達式):

#!/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。

BTW:我從here改編UnicodeDictWriter類。只需滾動兩個或三個屏幕,你會發現原來的UnicodeWriter類。

+1

非常感謝!它與我的原始字符串非常吻合! =) – Kamilla

+1

再次感謝你。它的工作非常好!看看:https://github.com/KamillaaaH/LucidScrapy =) – Kamilla

相關問題