2012-12-02 42 views
10

Tôi đang phân tích cú pháp một số dữ liệu có định dạng chuẩn giống như 10 pizzas. Đôi khi, dữ liệu được nhập chính xác và chúng tôi có thể kết thúc với 5pizzas thay vì 5 pizzas. Trong kịch bản này, tôi muốn phân tích số lượng pizza.Tách một chuỗi nơi nó chuyển đổi giữa các ký tự số và chữ cái

Cách ngây thơ để làm điều này là kiểm tra ký tự theo ký tự, tạo chuỗi cho đến khi chúng tôi đạt đến số không và sau đó truyền chuỗi đó làm số nguyên.

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

Điều này khá là khó khăn. Có cách nào dễ dàng hơn để tách một chuỗi mà nó chuyển từ chữ số sang ký tự chữ cái?

Trả lời

15

Bạn hỏi một cách để tách một chuỗi trên chữ số, nhưng sau đó trong ví dụ của bạn, những gì bạn thực sự muốn chỉ là những con số đầu tiên, điều này được thực hiện dễ dàng với itertools.takewhile():

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

Điều này làm cho rất nhiều ý nghĩa - những gì chúng tôi đang làm là lấy ký tự từ chuỗi trong khi chúng là chữ số. Điều này có lợi thế là ngừng xử lý ngay khi chúng tôi nhận được ký tự đầu tiên không phải chữ số.

Nếu bạn cần dữ liệu sau quá, sau đó những gì bạn đang tìm kiếm là itertools.groupby() hỗn hợp với một đơn giản list comprehension:

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

Nếu sau đó bạn muốn thực hiện một số khổng lồ:

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

Làm thế nào về một regex?

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

Để chia chuỗi tại chữ số bạn có thể sử dụng re.split với cụm từ thông \d+:

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

Để tìm việc sử dụng số đầu tiên re.search:

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

Nếu bạn biết số phải ở đầu chuỗi sau đó bạn có thể sử dụng re.match thay vì re.search. Nếu bạn muốn tìm tất cả các số và loại bỏ phần còn lại, bạn có thể sử dụng re.findall.

Các vấn đề liên quan