पायथन में स्ट्रिंग से सभी गैर-संख्यात्मक वर्णों को हटाना


जवाबों:



90

यकीन नहीं होता कि यह सबसे कुशल तरीका है, लेकिन:

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

''.joinभाग साधन के बीच में कोई भी वर्ण एक साथ सभी परिणामी वर्ण गठबंधन करने के लिए। फिर इसके बाकी हिस्सों की एक सूची है, जहां (जैसा कि आप शायद अनुमान लगा सकते हैं) हम केवल स्ट्रिंग के कुछ हिस्सों को लेते हैं जो स्थिति से मेल खाते हैं isdigit


1
जो इसके विपरीत करता है। मुझे लगता है कि आपका मतलब है "नहीं c.isdigit ()"
रयान आर। रोसारियो

7
सभी गैर-संख्यात्मक निकालें == केवल संख्यात्मक रखें।
मार्क रस्कॉफ़

10
मुझे पसंद है कि इस दृष्टिकोण को इस सरल कार्य के लिए फिर से खींचने की आवश्यकता नहीं है।
विजयी

ध्यान दें कि str.translate का उपयोग करने वाले कार्यान्वयन के विपरीत, यह समाधान अजगर 2.7 और 3.4 दोनों में काम करता है। धन्यवाद!
एलेक्स

1
मुझे यह विकल्प पसंद है। एक रेगीक्स का उपयोग करना मुझे भारी लगता है।
अल्फ्रेडोकेमबरा 15

18

यह 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))

9

बस मिश्रण में एक और विकल्प जोड़ने के लिए, stringमॉड्यूल के भीतर कई उपयोगी स्थिरांक हैं । अन्य मामलों में अधिक उपयोगी होते हुए भी, उनका उपयोग यहां किया जा सकता है।

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

मॉड्यूल में कई स्थिरांक हैं, जिनमें शामिल हैं:

  • ascii_letters (AbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ)
  • hexdigits (0123456789abcdefABCDEF)

यदि आप इन स्थिरांक का भारी उपयोग कर रहे हैं, तो यह एक को कवर करने के लिए सार्थक हो सकता है frozenset। यह O (n) के बजाय O (1) लुकअप को सक्षम करता है, जहां n मूल स्ट्रिंग्स के लिए स्थिरांक की लंबाई है।

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

'' .join (c के लिए c में "abc123def456" अगर c.isdigit ()) मेरे python 3.4 में काम करता है
Eino Mkkitalo

7

@Ned Batchelder और @newacct ने सही जवाब दिया, लेकिन ...

यदि आपके पास अपनी स्ट्रिंग में अल्पविराम (,) दशमलव (।) है तो बस:

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

5

सबसे तेज़ दृष्टिकोण, यदि आपको केवल एक या दो ऐसे निष्कासन ऑपरेशन (या यहां तक ​​कि सिर्फ एक, लेकिन बहुत लंबे स्ट्रिंग पर!) से अधिक प्रदर्शन करने की आवश्यकता है, तो स्ट्रिंग्स की 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विधि अलग हो सकता है एक बालक उपयोग करने के लिए आसान सरल है, और, यूनिकोड तार पर की तुलना में यह बाइट तार पर है, Btw:

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

आप एक वास्तविक तानाशाह के बजाय एक मैपिंग क्लास का उपयोग करना चाह सकते हैं, खासकर अगर आपके यूनिकोड स्ट्रिंग में संभवतः बहुत उच्च ऑर्ड वैल्यू वाले वर्ण हो सकते हैं (जो कि तानाशाह को अत्यधिक बड़ा कर देगा; ;-) उदाहरण के लिए:

>>> 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) हार्ड-कोड मैजिक नंबर्स न करें; s / 65536 / sys.maxunicode / (2) तानाशाह बिना शर्त "अत्यधिक बड़े" है क्योंकि इनपुट में "संभावित रूप से" (sys.maxunicode - number_of_non_numeric_chars)प्रविष्टियां हो सकती हैं। (3) विचार करें कि क्या string.digits को खोलने के लिए यूनिकोडेटा मॉड्यूल को खोलने के लिए दरार की आवश्यकता के लिए पर्याप्त अग्रणी नहीं हो सकता है (4) पर विचार करें। सादगी और क्षमता के लिए re.sub (r '(? U) \ D +', u '', टेक्स्ट) पर विचार करें। गति।
जॉन माकिन

2

कई सही जवाब लेकिन मामले में आप इसे एक फ्लोट में चाहते हैं, सीधे, रेगेक्स का उपयोग किए बिना:

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.