ฉันจะลบอักขระทั้งหมดยกเว้นตัวเลขออกจากสตริงได้อย่างไร
ฉันจะลบอักขระทั้งหมดยกเว้นตัวเลขออกจากสตริงได้อย่างไร
คำตอบ:
ใน Python 2. * วิธีที่เร็วที่สุดคือ.translate
วิธีการ:
>>> x='aaa12333bb445bb54b5b52'
>>> import string
>>> all=string.maketrans('','')
>>> nodigs=all.translate(all, string.digits)
>>> x.translate(all, nodigs)
'1233344554552'
>>>
string.maketrans
สร้างตารางการแปล (สตริงความยาว 256) ซึ่งในกรณีนี้จะเหมือนกับ''.join(chr(x) for x in range(256))
(เร็วกว่าที่จะทำ ;-) .translate
ใช้ตารางการแปล (ซึ่งตรงนี้ไม่เกี่ยวข้องเนื่องจากall
โดยพื้นฐานแล้วหมายถึงเอกลักษณ์) และลบอักขระที่มีอยู่ในอาร์กิวเมนต์ที่สอง - ส่วนสำคัญ
.translate
การทำงานแตกต่างกันมากในสาย Unicode (และสตริงในหลาม 3 - ฉันทำคำถามปรารถนาระบุที่สำคัญการเปิดตัวของงูหลามเป็นที่น่าสนใจ!) - ไม่ได้ค่อนข้างง่ายนี้ไม่ได้ค่อนข้างเร็วนี้แม้ว่าจะยังคงใช้งานได้ค่อนข้าง
กลับไปที่ 2. * ประสิทธิภาพที่แตกต่างนั้นน่าประทับใจ ... :
$ 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
การเร่งให้เร็วขึ้น 7-8 เท่าแทบจะไม่ใช่ถั่วลิสงดังนั้นtranslate
วิธีนี้จึงคุ้มค่าที่จะรู้และใช้ แนวทางอื่นที่ไม่ใช่ RE ยอดนิยม ... :
$ python -mtimeit -s'x="aaa12333bb445bb54b5b52"' '"".join(i for i in x if i.isdigit())'
100000 loops, best of 3: 11.5 usec per loop
ช้ากว่า RE 50% ดังนั้น.translate
แนวทางจึงเต้นตามลำดับขนาด
ใน Python 3 หรือสำหรับ Unicode คุณต้องส่งผ่าน.translate
การแมป (โดยมีลำดับไม่ใช่อักขระโดยตรงเป็นคีย์) ที่ส่งคืนNone
สิ่งที่คุณต้องการลบ นี่เป็นวิธีที่สะดวกในการแสดงสิ่งนี้สำหรับการลบ "ทุกอย่างยกเว้น" อักขระเพียงไม่กี่ตัว:
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)
'1233344554552'
ยังส่งเสียง อย่างไรก็ตามการใส่สิ่งนี้ใน xx.py เรามี ... :
$ 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
... ซึ่งแสดงให้เห็นถึงความได้เปรียบด้านประสิทธิภาพจะหายไปสำหรับงาน "การลบ" ประเภทนี้และจะทำให้ประสิทธิภาพลดลง
x.translate(None, string.digits)
ได้ผลลัพธ์จริง'aaabbbbbb'
ซึ่งตรงกันข้ามกับสิ่งที่ตั้งใจไว้
all
builtin ... ไม่แน่ใจเกี่ยวกับเรื่องนั้น!
ใช้re.sub
ดังนี้:
>>> import re
>>> re.sub('\D', '', 'aas30dsa20')
'3020'
\D
จับคู่อักขระที่ไม่ใช่ตัวเลขดังนั้นโค้ดด้านบนจึงแทนที่อักขระที่ไม่ใช่ตัวเลขทุกตัวสำหรับสตริงว่าง
หรือคุณสามารถใช้filter
เช่นนี้ (ใน Python 2):
>>> filter(str.isdigit, 'aas30dsa20')
'3020'
เนื่องจากใน Python 3 ให้filter
ส่งคืนตัววนซ้ำแทน a list
คุณสามารถใช้สิ่งต่อไปนี้แทน:
>>> ''.join(filter(str.isdigit, 'aas30dsa20'))
'3020'
isdigit
เครื่องกำเนิดไฟฟ้าisdigt
อยู่กึ่งกลางระหว่างพวกเขา
r
สำหรับสตริงดิบ:re.sub(r"\D+", "", "aas30dsa20")
s=''.join(i for i in s if i.isdigit())
ตัวแปรเครื่องกำเนิดไฟฟ้าอื่น
s = ''.join(i for i in s if i.isdigit() or i in '-./\\')
คุณสามารถใช้ตัวกรอง:
filter(lambda x: x.isdigit(), "dasdasd2313dsa")
ใน python3.0 คุณต้องเข้าร่วมสิ่งนี้ (ค่อนข้างน่าเกลียด :()
''.join(filter(lambda x: x.isdigit(), "dasdasd2313dsa"))
str
เพื่อlist
ให้แน่ใจว่าใช้งานได้ทั้ง py2 และ py3:''.join(filter(lambda x: x.isdigit(), list("dasdasd2313dsa")))
ตามแนวของคำตอบของไบเออร์:
''.join(i for i in s if i.isdigit())
-
ไม่ใช่ตัวเลข
x.translate(None, string.digits)
จะลบตัวเลขทั้งหมดออกจากสตริง ในการลบตัวอักษรและเก็บตัวเลขให้ทำดังนี้:
x.translate(None, string.letters)
TypeError
: translate () รับอาร์กิวเมนต์เดียว (ให้ 2 ตัว) ทำไมคำถามนี้ถึงได้รับการโหวตในสถานะปัจจุบันจึงค่อนข้างน่าหงุดหงิด
ฝ่ายปฏิบัติการกล่าวถึงในความคิดเห็นว่าเขาต้องการคงตำแหน่งทศนิยมไว้ ซึ่งสามารถทำได้ด้วยเมธอด re.sub (ตามคำตอบที่สองและ IMHO ที่ดีที่สุด) โดยระบุตัวละครที่จะเก็บไว้อย่างชัดเจนเช่น
>>> re.sub("[^0123456789\.]","","poo123.4and5fish")
'123.45'
เวอร์ชันที่รวดเร็วสำหรับ 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)
นี่คือการเปรียบเทียบประสิทธิภาพกับ 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
ดังนั้นฉันจึงเร็วกว่า regex 3 เท่าเล็กน้อย นอกจากนี้ยังเร็วกว่าclass Del
ด้านบนเนื่องจากdefaultdict
การค้นหาทั้งหมดเป็นภาษา C แทนที่จะเป็น Python (ช้า) นี่คือเวอร์ชันในระบบเดียวกันของฉันสำหรับการเปรียบเทียบ
$ python3.3 -mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"' 'x.translate(xx.DD)'
100000 loops, best of 3: 13.6 usec per loop
ใช้นิพจน์ตัวสร้าง:
>>> s = "foo200bar"
>>> new_s = "".join(i for i in s if i in "0123456789")
''.join(n for n in foo if n.isdigit())
น่าเกลียด แต่ใช้งานได้:
>>> s
'aaa12333bb445bb54b5b52'
>>> a = ''.join(filter(lambda x : x.isdigit(), s))
>>> a
'1233344554552'
>>>
list(s)
?
filter(lambda x: x.isdigit(), s)
ทำงานได้ดีสำหรับฉัน ... โอ้เป็นเพราะฉันใช้ Python 2.7
คุณสามารถอ่านอักขระแต่ละตัว ถ้าเป็นตัวเลขให้รวมไว้ในคำตอบ str.isdigit()
วิธีเป็นวิธีที่จะรู้ว่าตัวละครเป็นหลัก
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 ลูปดีที่สุดคือ 3: 2.48 usec ต่อลูป
$ python -mtimeit -s'import re; x="aaa12333bab445bb54b5b52"' '"".join(re.findall("[a-z]+",x))'
100000 ลูปที่ดีที่สุดคือ 3: 2.02 usec ต่อลูป
$ python -mtimeit -s'import re; x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 ลูปดีที่สุดคือ 3: 2.37 usec ต่อลูป
$ python -mtimeit -s'import re; x="aaa12333bab445bb54b5b52"' '"".join(re.findall("[a-z]+",x))'
100000 ลูปที่ดีที่สุดคือ 3: 1.97 usec ต่อลูป
ฉันสังเกตว่าการเข้าร่วมนั้นเร็วกว่าย่อย
ไม่ใช่ซับเดียว แต่ง่ายมาก:
buffer = ""
some_str = "aas30dsa20"
for char in some_str:
if not char.isdigit():
buffer += char
print( buffer )
ฉันใช้สิ่งนี้ 'letters'
ควรมีตัวอักษรทั้งหมดที่คุณต้องการกำจัด:
Output = Input.translate({ord(i): None for i in 'letters'}))
ตัวอย่าง:
Input = "I would like 20 dollars for that suit"
Output = Input.translate({ord(i): None for i in 'abcdefghijklmnopqrstuvwxzy'}))
print(Output)
เอาท์พุต:
20
my_string="sdfsdfsdfsfsdf353dsg345435sdfs525436654.dgg("
my_string=''.join((ch if ch in '0123456789' else '') for ch in my_string)
print(output:+my_string)
เอาต์พุต: 353345435525436654