2010-09-04 32 views
10

Tôi cần phải thay thế các ký tự không phải số bằng một chuỗi.Thay thế các ký tự không phải là số

Ví dụ: "8-4545-225-144" cần phải là "84545225144"; "$ 334fdf890 == -" phải là "334890".

Tôi làm cách nào để thực hiện việc này?

Trả lời

17
''.join(c for c in S if c.isdigit()) 
+0

Tôi ghét nó khi mọi người đập một danh sách hiểu khi biểu thức máy phát điện là tùy chọn phù hợp. Bạn, thưa bạn, giành chiến thắng một internet (và một upvote). – delnan

+0

+1 cho giải pháp phi regex. tôi ghét khi mọi người sử dụng regex cho mọi thứ, một số mục tiêu phù hợp hơn với giải pháp phi regex – killown

+1

@killown: Cá nhân tôi tìm thấy tùy chọn regex dễ đọc hơn. Có lẽ đó là bởi vì tôi đã làm rất nhiều công việc với regexes, nhưng nhìn vào mã của @ KennyTM tôi có thể thấy ngay lập tức những gì nó làm; điều này đưa tôi một giây để hiểu. –

17

Có thể với regex.

import re 

... 

return re.sub(r'\D', '', theString) 
0

Mặc dù một chút phức tạp hơn để thiết lập, sử dụng phương pháp translate() chuỗi để xóa các ký tự như hình dưới đây có thể càng nhiều càng tốt 4-6 lần nhanh hơn so với sử dụng join() hoặc re.sub() theo kiểm tra thời gian tôi thực hiện - vì vậy nếu nó là một cái gì đó thực hiện nhiều lần, bạn có thể muốn xem xét việc sử dụng này để thay thế.

nonnumerics = ''.join(c for c in ''.join(chr(i) for i in range(256)) if not c.isdigit()) 

astring = '123-$ab #6789' 
print astring.translate(None, nonnumerics) 
# 1236789 
+0

Phương thức str.translate được ưu tiên hơn string.translate. –

+0

@Roger Pate, điểm tốt, thói quen cũ rất khó để phá vỡ ... Tôi đã cập nhật mã trong câu trả lời của tôi cho phù hợp.Cảm ơn bạn đã chỉ ra và cho phép tôi cải thiện mã mẫu. – martineau

0

Tôi thích biểu thức thông thường, vì vậy đây là một cách nếu bạn thích

import re 
myStr = '$334fdf890==-' 
digts = re.sub('[^0-9]','',myStr) 

này nên thay thế tất cả các lần xuất hiện nonnumeric với '' nghĩa là không có gì. Vì vậy, biến digts nên '334.890'

1

Hãy thời gian joinre phiên bản:

In [3]: import re 

In [4]: def withRe(theString): return re.sub('\D', '', theString) 
    ...: 

In [5]: 

In [6]: def withJoin(S): return ''.join(c for c in S if c.isdigit()) 
    ...: 


In [11]: s = "8-4545-225-144" 

In [12]: %timeit withJoin(s) 
100000 loops, best of 3: 6.89 us per loop 

In [13]: %timeit withRe(s) 
100000 loops, best of 3: 4.77 us per loop 

Phiên bản join là đẹp hơn nhiều, so với re một, nhưng tiếc là chậm hơn 50%. Vì vậy, nếu hiệu suất là một vấn đề, sự thanh lịch có thể cần phải được hy sinh.

EDIT

In [16]: def withFilter(s): return filter(str.isdigit, s) 
    ....: 
In [19]: %timeit withFilter(s) 
100000 loops, best of 3: 2.75 us per loop 

Dường như filter là hiệu suất và khả năng đọc chiến thắng

3

filter(str.isdigit, s) là nhanh hơn và rõ ràng hơn IMO hơn bất cứ điều gì khác được liệt kê ở đây.

Nó cũng sẽ ném một TypeError nếu s là một loại unicode. Tùy thuộc vào định nghĩa của "chữ số" bạn muốn, điều này có thể hữu ích hơn hoặc ít hơn thay thế filter(type(s).isdigit, s), hơi chậm hơn nhưng vẫn nhanh hơn các phiên bản đọc lại và hiểu cho tôi.

Chỉnh sửa: Mặc dù nếu bạn là kẻ hút kém bị mắc kẹt với Python 3, bạn sẽ cần phải sử dụng "".join(filter(str.isdigit, s)) giúp bạn vững chắc trong lĩnh vực có hiệu suất kém tương đương. Tiến bộ như vậy.

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