2012-01-21 7 views
12

मैं उबंटू पर sensors उपयोगिता के आउटपुट के लिए एक साधारण नियमित अभिव्यक्ति पार्सर लिख रहा हूं। यहाँ टेक्स्ट की पंक्ति में मैं पार्स करने कर रहा हूँ का एक उदाहरण है:नियमित अभिव्यक्तियों के साथ पोर्टेबल (यूनिकोड) डिग्री प्रतीक को कैसे पार्स करें?

temp1:  +31.0°C (crit = +107.0°C) 

और यहाँ regex मैं मैच के लिए कि (अजगर में) का उपयोग कर रहा है:

temp_re = re.compile(r'(temp1:)\s+(\+|-)(\d+\.\d+)\W\WC\s+' 
        r'\(crit\s+=\s+(\+|-)(\d+\.\d+)\W\WC\).*') 

इस कोड के रूप में की उम्मीद है और मैचों काम करता है उदाहरण पाठ मैंने ऊपर दिया है। केवल बिट्स मैं वास्तव में दिलचस्पी रखता हूँ नंबर दिए गए हैं, तो यह थोड़ा:

(\+|-)(\d+\.\d+)\W\WC 

जो + या - हस्ताक्षर का मिलान करके शुरू होता है और °C मिलान करते हुए समाप्त होता है।

मेरा सवाल है, यह (गैर-अल्फान्यूमेरिक) वर्णों को ° से मेल खाने के लिए क्यों लेता है? क्या सिस्टम उन सिस्टम पर टूट जाएगा जहां यूनिकोड का अलग-अलग प्रतिनिधित्व किया जाता है? यदि हां, तो मैं इसे पोर्टेबल कैसे बना सकता हूं?

+2

're.UNICODE' ध्वज – netvope

+0

're.UNICODE' ध्वज के साथ प्रयास करें कि आरई या तो \ \ W \ WC' या' WC' के साथ मेल नहीं खाता है। या, क्या मैंने आपको गलत समझा है? – snim2

+1

"' ℃ '" भी है, जो एक _single_ वर्ण है जिसका मतलब डिग्री सेल्सियस है। धन्यवाद एक गुच्छा, यूनिकोड कंसोर्टियम! –

उत्तर

8

संभव पोर्टेबल समाधान:

Convert इनपुट यूनिकोड करने के लिए डेटा, और नियमित अभिव्यक्ति में re.UNICODE ध्वज का उपयोग करें।

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


data = u'temp1:  +31.0°C (crit = +107.0°C)' 
temp_re = re.compile(ur'(temp1:)\s+(\+|-)(\d+\.\d+)°C\s+' 
        ur'\(crit\s+=\s+(\+|-)(\d+\.\d+)°C\).*', flags=re.UNICODE) 

print temp_re.findall(data) 

आउटपुट

[(u'temp1:', u'+', u'31.0', u'+', u'107.0')] 

संपादित

@netvope allready प्रश्न के लिए टिप्पणी में इस ओर इशारा किया। इनपुट एनकोडिंग के बारे में J.F. Sebastian टिप्पणियों से

अद्यतन

नोट्स:

check_output() रिटर्न बाइनरी डेटा है कि कभी कभी पाठ हो सकता है (कि इस मामले में एक ज्ञात वर्ण एन्कोडिंग होना चाहिए और आप इसे परिवर्तित कर सकते हैं यूनिकोड के लिए)। वैसे भी ord (u '°') == 176 इसलिए इसे ASCII एन्कोडिंग का उपयोग करके एन्कोड नहीं किया जा सकता है।

तो, unicode के लिए इनपुट डेटा को डिकोड करने, मूल रूप से * यदि आप locale.getpreferredencoding() का उपयोग कर सिस्टम स्थान से एन्कोडिंग का उपयोग करना चाहिए जैसे:

data = subprocess.check_output(...).decode(locale.getpreferredencoding()) 

डेटा के साथ सही ढंग से इनकोडिंग:

आप मिल जाएगा इस मामले में re.UNICODE के बिना एक ही आउटपुट।


क्यों मूल रूप से?क्योंकि cp1251 के साथ रूसी Win7 पर के रूप में preferredencoding हम उदाहरण script.py जो डीकोड यह utf-8 के उत्पादन है के लिए है, तो:

#!/usr/bin/env python 
# -*- coding: utf8 -*- 

print u'temp1: +31.0°C (crit = +107.0°C)'.encode('utf-8') 

और यह उत्पादन है पार्स करने के लिए सुबह की जरूरत:

subprocess.check_output(['python', 
         'script.py']).decode(locale.getpreferredencoding()) 

गलत परिणाम देगा: 'В°' बजाय °

इसलिए आपको कुछ मामलों में इनपुट डेटा के एन्कोडिंग को जानने की आवश्यकता है।

+0

निश्चित रूप से, लेकिन इस तरह की चीज़ के लिए एक पूर्ण कामकाजी उदाहरण हमेशा एक अच्छा विचार है। पूर्ण सुविधाओं के उपलब्ध होने पर भी कई प्रोग्रामर के लिए यूनिकोड को संभालना मुश्किल है :( –

+0

+1: "इनपुट डेटा को यूनिकोड में कनवर्ट करें" के लिए। बीटीडब्ल्यू, आपको इस मामले में 're.UNICODE' के बिना एक ही आउटपुट मिल जाएगा। – jfs

+0

इसके लिए धन्यवाद। मेरे पास "असली" कोड है। डेटा वास्तव में कॉल के आउटपुट से 'subprocess.check_output' तक आता है जो अपने डेटा को ASCII के रूप में देता है, यूनिकोड नहीं, इसलिए यह' टी वहाँ काफी काम नहीं करता है। शायद एक और समझदार चीज़ पाइथन 3 पर जाना होगा जहां "सब कुछ" यूनिकोड है? हम्म। – snim2

संबंधित मुद्दे