Xóa tất cả các ký tự không phải là số khỏi chuỗi trong Python


Câu trả lời:


267
>>> import re
>>> re.sub("[^0-9]", "", "sdkjh987978asd098as0980a98sd")
'987978098098098'

89
đó có thể là re.sub (r "\ D", "", "sdkjh987978asd098as0980a98sd")
newacct

2
và đó có thể là: từ tái nhập phụ
James Koss

88

Không chắc đây có phải là cách hiệu quả nhất không, nhưng:

>>> ''.join(c for c in "abc123def456" if c.isdigit())
'123456'

Phần này ''.joincó nghĩa là kết hợp tất cả các ký tự kết quả lại với nhau mà không có bất kỳ ký tự nào ở giữa. Sau đó, phần còn lại của nó là một sự hiểu biết danh sách, trong đó (như bạn có thể đoán) chúng ta chỉ lấy các phần của chuỗi phù hợp với điều kiện isdigit.


1
Điều đó làm ngược lại. Tôi nghĩ bạn có nghĩa là "không phải c.itorigit ()"
Ryan R. Rosario

7
Xóa tất cả không phải là số == chỉ giữ số.
Mark Rushakoff

10
Tôi thích cách tiếp cận này không yêu cầu kéo lại, cho chức năng đơn giản này.
triunenature

Lưu ý rằng không giống như việc triển khai bằng str.translate, giải pháp này hoạt động trong cả python 2.7 và 3.4. Cảm ơn bạn!
Alex

1
Tôi thích sự thay thế này. Sử dụng một regex dường như quá mức cần thiết với tôi.
alfredocambera

18

Điều này sẽ hoạt động cho cả chuỗi và đối tượng unicode trong Python2 và cả chuỗi và byte trong Python3:

# python <3.0
def only_numerics(seq):
    return filter(type(seq).isdigit, seq)

# python ≥3.0
def only_numerics(seq):
    seq_type= type(seq)
    return seq_type().join(filter(seq_type.isdigit, seq))

9

Chỉ cần thêm tùy chọn khác vào hỗn hợp, có một số hằng hữu ích trong stringmô-đun. Mặc dù hữu ích hơn trong các trường hợp khác, chúng có thể được sử dụng ở đây.

>>> from string import digits
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'

Có một số hằng số trong mô-đun, bao gồm:

  • ascii_letters (abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ)
  • hexdigits (0123456789abcdefABCDEF)

Nếu bạn đang sử dụng các hằng số này rất nhiều, có thể đáng để chuyển đổi chúng thành a frozenset. Điều đó cho phép tra cứu O (1), thay vì O (n), trong đó n là độ dài của hằng số cho các chuỗi gốc.

>>> digits = frozenset(digits)
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'

'' .join (c cho c trong "abc123def456" nếu c.isdigit ()) hoạt động trong python của tôi 3.4
Eino MAKITALO

7

@Ned Batchelder và @newacct đã cung cấp câu trả lời đúng, nhưng ...

Chỉ trong trường hợp nếu bạn có dấu phẩy (,) thập phân (.) Trong chuỗi của bạn:

import re
re.sub("[^\d\.]", "", "$1,999,888.77")
'1999888.77'

5

Cách tiếp cận nhanh nhất, nếu bạn cần thực hiện nhiều hơn một hoặc hai thao tác loại bỏ như vậy (hoặc thậm chí chỉ một, nhưng trên một chuỗi rất dài! -), là dựa vào translatephương thức chuỗi, mặc dù nó cần một số chuẩn bị:

>>> import string
>>> allchars = ''.join(chr(i) for i in xrange(256))
>>> identity = string.maketrans('', '')
>>> nondigits = allchars.translate(identity, string.digits)
>>> s = 'abc123def456'
>>> s.translate(identity, nondigits)
'123456'

Các translatephương pháp là khác nhau, và có lẽ một chút đơn giản đơn giản để sử dụng, trên chuỗi Unicode hơn là trên dây byte, btw:

>>> unondig = dict.fromkeys(xrange(65536))
>>> for x in string.digits: del unondig[ord(x)]
... 
>>> s = u'abc123def456'
>>> s.translate(unondig)
u'123456'

Bạn có thể muốn sử dụng một lớp ánh xạ hơn là một dict thực tế, đặc biệt là nếu chuỗi Unicode của bạn có khả năng chứa các ký tự có giá trị thứ tự rất cao (điều đó sẽ khiến cho dict quá lớn ;-). Ví dụ:

>>> class keeponly(object):
...   def __init__(self, keep): 
...     self.keep = set(ord(c) for c in keep)
...   def __getitem__(self, key):
...     if key in self.keep:
...       return key
...     return None
... 
>>> s.translate(keeponly(string.digits))
u'123456'
>>> 

2
(1) Đừng để số ma thuật mã cứng; s / 65536 / sys.maxunicode / (2) Dict là "quá lớn" vô điều kiện vì đầu vào "có thể có khả năng" chứa (sys.maxunicode - number_of_non_numeric_chars)các mục. (3) xem xét liệu chuỗi.digits có thể không đủ dẫn đến nhu cầu bẻ khóa mô-đun unicodingata (4) xem xét re.sub (r '(? U) \ D +', u '', văn bản) để đơn giản và tiềm năng tốc độ.
John Machin

2

Nhiều câu trả lời đúng nhưng trong trường hợp bạn muốn nó nổi, trực tiếp, không sử dụng regex:

x= '$123.45M'

float(''.join(c for c in x if (c.isdigit() or c =='.'))

123,45

Bạn có thể thay đổi điểm cho dấu phẩy tùy theo nhu cầu của bạn.

thay đổi cho điều này nếu bạn biết số của bạn là một số nguyên

x='$1123'    
int(''.join(c for c in x if c.isdigit())

1123

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.