Bagaimana cara menghapus semua karakter kecuali angka dari string?
Bagaimana cara menghapus semua karakter kecuali angka dari string?
Jawaban:
Dalam Python 2. *, sejauh ini pendekatan tercepat adalah .translate
metode:
>>> x='aaa12333bb445bb54b5b52'
>>> import string
>>> all=string.maketrans('','')
>>> nodigs=all.translate(all, string.digits)
>>> x.translate(all, nodigs)
'1233344554552'
>>>
string.maketrans
membuat tabel terjemahan (string dengan panjang 256) yang dalam hal ini sama dengan ''.join(chr(x) for x in range(256))
(hanya lebih cepat membuatnya ;-). .translate
menerapkan tabel terjemahan (yang di sini tidak relevan karena all
pada dasarnya berarti identitas) DAN menghapus karakter yang ada di argumen kedua - bagian kunci.
.translate
bekerja sangat berbeda pada string Unicode (dan string di Python 3 - Saya melakukan pertanyaan keinginan tertentu yang besar-rilis Python adalah kepentingan!) - tidak cukup sederhana ini, tidak cukup cepat ini, meskipun masih cukup bermanfaat.
Kembali ke 2. *, perbedaan kinerja sangat mengesankan ...:
$ python -mtimeit -s'import string; all=string.maketrans("", ""); nodig=all.translate(all, string.digits); x="aaa12333bb445bb54b5b52"' 'x.translate(all, nodig)'
1000000 loops, best of 3: 1.04 usec per loop
$ python -mtimeit -s'import re; x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 loops, best of 3: 7.9 usec per loop
Mempercepat sebanyak 7-8 kali bukanlah hal yang mudah, jadi translate
metode ini layak untuk diketahui dan digunakan. Pendekatan non-RE populer lainnya ...:
$ python -mtimeit -s'x="aaa12333bb445bb54b5b52"' '"".join(i for i in x if i.isdigit())'
100000 loops, best of 3: 11.5 usec per loop
adalah 50% lebih lambat dari RE, sehingga .translate
pendekatan mengalahkannya dengan urutan besarnya.
Di Python 3, atau untuk Unicode, Anda perlu meneruskan .translate
pemetaan (dengan ordinal, bukan karakter secara langsung, sebagai kunci) yang mengembalikan None
apa yang ingin Anda hapus. Berikut cara mudah untuk mengungkapkannya untuk menghapus "semuanya kecuali" beberapa karakter:
import string
class Del:
def __init__(self, keep=string.digits):
self.comp = dict((ord(c),c) for c in keep)
def __getitem__(self, k):
return self.comp.get(k)
DD = Del()
x='aaa12333bb445bb54b5b52'
x.translate(DD)
juga memancarkan '1233344554552'
. Namun, meletakkan ini di xx.py kita memiliki ...:
$ python3.1 -mtimeit -s'import re; x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 loops, best of 3: 8.43 usec per loop
$ python3.1 -mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"' 'x.translate(xx.DD)'
10000 loops, best of 3: 24.3 usec per loop
... yang menunjukkan keuntungan kinerja menghilang, untuk jenis tugas "penghapusan", dan menjadi penurunan kinerja.
x.translate(None, string.digits)
sebenarnya menghasilkan 'aaabbbbbb'
, yang merupakan kebalikan dari apa yang dimaksudkan.
all
builtin ... tidak yakin tentang itu!
Gunakan re.sub
, seperti ini:
>>> import re
>>> re.sub('\D', '', 'aas30dsa20')
'3020'
\D
cocok dengan karakter non-digit apa pun, jadi, kode di atas, pada dasarnya menggantikan setiap karakter non-digit untuk string kosong.
Atau Anda dapat menggunakan filter
, seperti (dengan Python 2):
>>> filter(str.isdigit, 'aas30dsa20')
'3020'
Karena di Python 3, filter
mengembalikan iterator alih-alih a list
, Anda dapat menggunakan yang berikut ini:
>>> ''.join(filter(str.isdigit, 'aas30dsa20'))
'3020'
isdigit
, generator dengan isdigt
setengah jalan di antara mereka
r
untuk string mentah:re.sub(r"\D+", "", "aas30dsa20")
s=''.join(i for i in s if i.isdigit())
Varian generator lain.
s = ''.join(i for i in s if i.isdigit() or i in '-./\\')
Anda dapat menggunakan filter:
filter(lambda x: x.isdigit(), "dasdasd2313dsa")
Di python3.0 Anda harus bergabung dengan ini (agak jelek :()
''.join(filter(lambda x: x.isdigit(), "dasdasd2313dsa"))
str
ke list
untuk memastikannya berfungsi pada py2 dan py3:''.join(filter(lambda x: x.isdigit(), list("dasdasd2313dsa")))
di sepanjang garis jawaban bayer:
''.join(i for i in s if i.isdigit())
-
bukan digit.
x.translate(None, string.digits)
akan menghapus semua digit dari string. Untuk menghapus huruf dan menyimpan angka, lakukan ini:
x.translate(None, string.letters)
TypeError
: translate () mengambil tepat satu argumen (2 diberikan). Mengapa pertanyaan ini mendapat suara positif dalam kondisinya saat ini cukup membuat frustrasi.
Op tersebut menyebutkan di komentar bahwa dia ingin menyimpan tempat desimal. Ini dapat dilakukan dengan metode re.sub (sesuai dengan jawaban terbaik kedua dan IMHO) dengan secara eksplisit mencantumkan karakter yang akan disimpan misalnya
>>> re.sub("[^0123456789\.]","","poo123.4and5fish")
'123.45'
Versi cepat untuk Python 3:
# xx3.py
from collections import defaultdict
import string
_NoneType = type(None)
def keeper(keep):
table = defaultdict(_NoneType)
table.update({ord(c): c for c in keep})
return table
digit_keeper = keeper(string.digits)
Berikut perbandingan performa vs. regex:
$ python3.3 -mtimeit -s'import xx3; x="aaa12333bb445bb54b5b52"' 'x.translate(xx3.digit_keeper)'
1000000 loops, best of 3: 1.02 usec per loop
$ python3.3 -mtimeit -s'import re; r = re.compile(r"\D"); x="aaa12333bb445bb54b5b52"' 'r.sub("", x)'
100000 loops, best of 3: 3.43 usec per loop
Jadi ini sedikit lebih dari 3 kali lebih cepat daripada regex, bagi saya. Ini juga lebih cepat daripada di class Del
atas, karena defaultdict
semua pencariannya di C, daripada Python (lambat). Ini versi itu di sistem saya yang sama, untuk perbandingan.
$ python3.3 -mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"' 'x.translate(xx.DD)'
100000 loops, best of 3: 13.6 usec per loop
Jelek tapi berhasil:
>>> s
'aaa12333bb445bb54b5b52'
>>> a = ''.join(filter(lambda x : x.isdigit(), s))
>>> a
'1233344554552'
>>>
list(s)
?
filter(lambda x: x.isdigit(), s)
bekerja dengan baik untuk saya. ... oh, itu karena saya menggunakan Python 2.7.
Anda dapat membaca setiap karakter. Jika berupa digit, masukkan ke dalam jawaban. The str.isdigit()
Metode adalah cara untuk mengetahui apakah karakter adalah digit.
your_input = '12kjkh2nnk34l34'
your_output = ''.join(c for c in your_input if c.isdigit())
print(your_output) # '1223434'
$ python -mtimeit -s'import re; x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 loop, terbaik 3: 2,48 usec per loop
$ python -mtimeit -s'import re; x="aaa12333bab445bb54b5b52"' '"".join(re.findall("[a-z]+",x))'
100000 loop, terbaik 3: 2.02 usec per loop
$ python -mtimeit -s'import re; x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 loop, terbaik 3: 2,37 usec per loop
$ python -mtimeit -s'import re; x="aaa12333bab445bb54b5b52"' '"".join(re.findall("[a-z]+",x))'
100000 loop, terbaik 3: 1,97 usec per loop
Saya telah mengamati bahwa join lebih cepat daripada sub.
Saya menggunakan ini. 'letters'
harus berisi semua huruf yang ingin Anda singkirkan:
Output = Input.translate({ord(i): None for i in 'letters'}))
Contoh:
Input = "I would like 20 dollars for that suit"
Output = Input.translate({ord(i): None for i in 'abcdefghijklmnopqrstuvwxzy'}))
print(Output)
Keluaran:
20
my_string="sdfsdfsdfsfsdf353dsg345435sdfs525436654.dgg("
my_string=''.join((ch if ch in '0123456789' else '') for ch in my_string)
print(output:+my_string)
keluaran: 353345435525436654