2012-12-02 10 views
10

मैं कुछ डेटा पार्स कर रहा हूं जहां मानक प्रारूप 10 pizzas जैसा कुछ है। कभी-कभी, डेटा सही ढंग से इनपुट होता है और हम 5 pizzas के बजाय 5pizzas के साथ समाप्त हो सकते हैं। इस परिदृश्य में, मैं पिज्जा की संख्या को पार्स करना चाहता हूं।एक स्ट्रिंग को विभाजित करना जहां यह संख्यात्मक और वर्णमाला वर्णों के बीच स्विच करता है

ऐसा करने का भद्दा तरीका चरित्र द्वारा चरित्र की जांच करना, स्ट्रिंग का निर्माण करना, जब तक कि हम एक गैर-अंक तक नहीं पहुंच जाते हैं और फिर उस स्ट्रिंग को पूर्णांक के रूप में कास्टिंग करते हैं।

num_pizzas = "" 
for character in data_input: 
    if character.isdigit(): 
     num_pizzas += character 
    else: 
     break 
num_pizzas = int(num_pizzas) 

हालांकि यह बहुत खराब है। क्या स्ट्रिंग को विभाजित करने का कोई आसान तरीका है जहां यह संख्यात्मक अंकों से वर्णमाला वर्णों में स्विच करता है?

उत्तर

15

आप एक तरह से अंक पर एक स्ट्रिंग को विभाजित करने के लिए पूछना है, लेकिन फिर अपने उदाहरण में, क्या आप वास्तव में चाहते हैं सिर्फ पहली संख्या है, इस itertools.takewhile() साथ आसानी से किया:

>>> int("".join(itertools.takewhile(str.isdigit, "10pizzas"))) 
10 

इस का एक बहुत बनाता है समझ - हम क्या कर रहे हैं चरित्र को स्ट्रिंग से लेते हुए वे अंक हैं। जैसे ही हम पहले गैर-अंकों के चरित्र तक पहुंचते हैं, इस पर प्रसंस्करण रोकने का लाभ होता है।

तुम भी बाद में डेटा की जरूरत है, तो क्या आप देख रहे हैं itertools.groupby() मिश्रित एक सरल list comprehension साथ में है:

>>> ["".join(x) for _, x in itertools.groupby("dfsd98sd8f68as7df56", key=str.isdigit)] 
['dfsd', '98', 'sd', '8', 'f', '68', 'as', '7', 'df', '56'] 

आप तो एक विशाल संख्या बनाना चाहते हैं:

>>> int("".join("".join(x) for is_number, x in itertools.groupby("dfsd98sd8f68as7df56", key=str.isdigit) if is_number is True)) 
98868756 
1

एक रेगेक्स के बारे में कैसे?

reg = re.compile(r'(?P<numbers>\d*)(?P<rest>.*)') 
result = reg.search(str) 
if result: 
    numbers = result.group('numbers') 
    rest = result.group('rest') 
11

अंक पर स्ट्रिंग विभाजित करने के लिए आप नियमित अभिव्यक्ति \d+ साथ re.split उपयोग कर सकते हैं: यदि आप नंबर पता है

>>> re.search('\d+', '5pizzas').group() 
'5' 
>>> re.search('\d+', 'foo123bar').group() 
'123' 

:

>>> import re 
>>> def my_split(s): 
    return filter(None, re.split(r'(\d+)', s)) 

>>> my_split('5pizzas') 
['5', 'pizzas'] 
>>> my_split('foo123bar') 
['foo', '123', 'bar'] 

पहले नंबर उपयोग re.search जानने के लिए स्ट्रिंग की शुरुआत में होना चाहिए, तो आप re.search के बजाय re.match का उपयोग कर सकते हैं। यदि आप सभी नंबरों को ढूंढना चाहते हैं और बाकी को छोड़ना चाहते हैं तो आप re.findall का उपयोग कर सकते हैं।

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