เราจะลบอักขระที่ไม่ใช่ตัวเลขทั้งหมดออกจากสตริงใน Python ได้อย่างไร
เราจะลบอักขระที่ไม่ใช่ตัวเลขทั้งหมดออกจากสตริงใน Python ได้อย่างไร
คำตอบ:
>>> import re
>>> re.sub("[^0-9]", "", "sdkjh987978asd098as0980a98sd")
'987978098098098'
ไม่แน่ใจว่านี่เป็นวิธีที่มีประสิทธิภาพมากที่สุดหรือไม่ แต่:
>>> ''.join(c for c in "abc123def456" if c.isdigit())
'123456'
''.join
ส่วนวิธีการที่จะรวมทุกตัวละครที่เกิดขึ้นร่วมกันโดยไม่มีอักขระใด ๆ ในระหว่าง จากนั้นส่วนที่เหลือเป็นความเข้าใจของรายการโดยที่ (ตามที่คุณคาดเดาได้) เราจะเอาเฉพาะส่วนของสตริงที่ตรงกับเงื่อนไขisdigit
เท่านั้น
สิ่งนี้จะใช้ได้ทั้งกับสตริงและวัตถุ unicode ใน Python2 และทั้งสตริงและไบต์ใน 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))
เพียงเพื่อเพิ่มตัวเลือกอื่นในการผสมมีค่าคงที่ที่มีประโยชน์หลายรายการในstring
โมดูล แม้ว่าจะมีประโยชน์มากกว่าในกรณีอื่น ๆ แต่ก็สามารถใช้ที่นี่ได้
>>> from string import digits
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'
มีหลายค่าคงที่ในโมดูลรวมถึง:
ascii_letters
(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ)hexdigits
(0123456789abcdefABCDEF)frozenset
หากคุณกำลังใช้คงที่เหล่านี้อย่างมากก็สามารถจะคุ้มค่าที่จะแอบแฝงพวกเขาไป ที่ทำให้การค้นหา O (1) มากกว่า O (n) โดยที่ n คือความยาวของค่าคงที่สำหรับสตริงดั้งเดิม
>>> digits = frozenset(digits)
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'
@Ned Batchelder และ @newacct ให้คำตอบที่ถูกต้อง แต่ ...
ในกรณีที่คุณมีเครื่องหมายจุลภาค (,) ทศนิยม (.) ในสตริงของคุณ:
import re
re.sub("[^\d\.]", "", "$1,999,888.77")
'1999888.77'
วิธีที่เร็วที่สุดหากคุณต้องการดำเนินการลบมากกว่าหนึ่งหรือสองครั้ง (หรือแม้แต่เพียงครั้งเดียว แต่ใช้สตริงที่ยาวมาก! -) คือต้องพึ่งพาtranslate
วิธีการของสตริงแม้ว่าจะต้องมีการเตรียมการบางอย่าง:
>>> 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'
translate
วิธีการที่แตกต่างกันและอาจตาดง่ายง่ายต่อการใช้งานในสาย Unicode มากกว่าที่เป็นอยู่ในสายไบต์ครับ:
>>> unondig = dict.fromkeys(xrange(65536))
>>> for x in string.digits: del unondig[ord(x)]
...
>>> s = u'abc123def456'
>>> s.translate(unondig)
u'123456'
คุณอาจต้องการใช้คลาสการแมปมากกว่า dict จริงโดยเฉพาะอย่างยิ่งถ้า Unicode สตริงของคุณอาจมีอักขระที่มีค่า ord สูงมาก (ซึ่งจะทำให้ dict ใหญ่เกินไป ;-) ตัวอย่างเช่น:
>>> 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'
>>>
(sys.maxunicode - number_of_non_numeric_chars)
รายการ (3) พิจารณาว่า string.digits อาจไม่เพียงพอที่จะนำไปสู่ความต้องการที่จะถอดรหัสเปิดโมดูล unicodedata (4) พิจารณา re.sub (r '(? u) \ D +', u '', text) เพื่อความเรียบง่ายและมีศักยภาพ ความเร็ว.
หลายคำตอบที่ถูกต้อง แต่ในกรณีที่คุณต้องการลอยตัวโดยตรงโดยไม่ต้องใช้ regex:
x= '$123.45M'
float(''.join(c for c in x if (c.isdigit() or c =='.'))
123.45
คุณสามารถเปลี่ยนจุดสำหรับเครื่องหมายจุลภาคขึ้นอยู่กับความต้องการของคุณ
เปลี่ยนสิ่งนี้ถ้าคุณรู้ว่าหมายเลขของคุณเป็นจำนวนเต็ม
x='$1123'
int(''.join(c for c in x if c.isdigit())
1123