अगर ASCII में पायथन में स्ट्रिंग है तो कैसे जांचें?


211

मैं यह जांचना चाहता हूं कि ASCII में कोई स्ट्रिंग है या नहीं।

मुझे पता है ord(), हालांकि जब मैं कोशिश करता ord('é')हूं, तो मेरे पास होता है TypeError: ord() expected a character, but string of length 2 found। मैं समझ गया कि यह उस तरह से हुआ है जिस तरह से मैंने पायथन का निर्माण किया (जैसा कि ord()'प्रलेखन में बताया गया है )।

क्या जाँच करने का कोई और तरीका है?


स्ट्रिंग एन्कोडिंग Python 2 और Python 3 के बीच काफी भिन्न है, इसलिए यह जानना अच्छा होगा कि आप किस संस्करण को लक्षित कर रहे हैं।
फ्लोरिसला

जवाबों:


188
def is_ascii(s):
    return all(ord(c) < 128 for c in s)

95
निरर्थक अक्षम। बहुत बेहतर है। s.decode ('ascii') को आज़माएं और विन्सेन्ट मार्सिफ़्टी द्वारा सुझाए गए अनुसार यूनिकोडडब्लॉसइर्रर को पकड़ें।
ddaa

20
यह अक्षम नहीं है। सभी () शॉर्ट-सर्किट होगा और एक अमान्य बाइट का सामना करते ही फाल्स लौटा देगा।
जॉन मिलिकिन

10
अक्षम या नहीं, अधिक पायथोनिक विधि कोशिश / को छोड़कर है।
जेरेमी कैंटरेल

43
यह कोशिश के अलावा अक्षम है / छोड़कर। यहाँ लूप दुभाषिया में है। कोशिश / फॉर्म को छोड़कर, लूप C कोडक कार्यान्वयन में है। जिसे str.decode ('ascii') द्वारा बुलाया जाता है। और मैं मानता हूँ, कोशिश / सिवाय रूप के और भी अधिक pythonic है।
डोडा

25
@ जॉनमोचिन ord(c) < 128की तुलना में असीम रूप से अधिक पठनीय और सहज ज्ञान युक्त हैc <= "\x7F"
स्लेटर विक्टरॉफ

252

मुझे लगता है कि आप सही सवाल नहीं पूछ रहे हैं--

अजगर में एक स्ट्रिंग के लिए 'ascii', utf-8, या किसी अन्य एन्कोडिंग के समान कोई संपत्ति नहीं है। आपके स्ट्रिंग के स्रोत (चाहे आप इसे किसी फ़ाइल से पढ़ते हैं, कीबोर्ड से इनपुट आदि) ने आपके स्ट्रिंग का उत्पादन करने के लिए एएससी में एक यूनिकोड स्ट्रिंग को एन्कोड किया हो सकता है, लेकिन यह वह जगह है जहां आपको उत्तर के लिए जाने की आवश्यकता है।

शायद आप जो सवाल पूछ सकते हैं, वह यह है: "क्या यह स्ट्रिंग एस्किसी में एक यूनिकोड स्ट्रिंग को एन्कोडिंग करने का परिणाम है?" - यह आप कोशिश करके जवाब दे सकते हैं:

try:
    mystring.decode('ascii')
except UnicodeDecodeError:
    print "it was not a ascii-encoded unicode string"
else:
    print "It may have been an ascii-encoded unicode string"

28
एन्कोड का उपयोग करना बेहतर है, क्योंकि पायथन 3 में स्ट्रिंग कोई डिकोड विधि नहीं है, देखें कि एन्कोड / डिकोड में क्या अंतर है? (अजगर 2.x)
जेट गुओ

@ श्री: ऐसा इसलिए है क्योंकि आप इसे एक अनकांशेड स्ट्रिंग ( strपायथन 2 में, bytesपायथन 3 में) पर उपयोग कर रहे हैं ।
dotancohen

पायथन 2 में, यह समाधान केवल एक यूनिकोड स्ट्रिंग के लिए काम करता है । एक strकिसी भी आईएसओ एन्कोडिंग में पहले यूनिकोड को एन्कोड करने की आवश्यकता होगी। उत्तर को इसमें जाना चाहिए।
एलेक्सिस

@ जेटगू: आपको इनपुट प्रकार के आधार पर दोनों का उपयोग करना चाहिए: s.decode('ascii') if isinstance(s, bytes) else s.encode('ascii')पायथन 3 में। ओपी का इनपुट एक बाइटस्ट्रिंग 'é'(अजगर 2 वाक्यविन्यास है, पायथन 3 उस समय जारी नहीं किया गया था) और इसलिए .decode()सही है।
10

2
@alexis: गलत है। strपायथन 2 पर एक बाइटस्ट्रिंग है। यह .decode('ascii')पता लगाने के लिए उपयोग करना सही है कि सभी बाइट्स एएससीआई रेंज में हैं या नहीं।
10

153

पायथन 3 रास्ता:

isascii = lambda s: len(s) == len(s.encode())

जाँच करने के लिए, परीक्षण स्ट्रिंग पास करें:

str1 = "♥O◘♦♥O◘♦"
str2 = "Python"

print(isascii(str1)) -> will return False
print(isascii(str2)) -> will return True

7
यह यूनिकोड स्ट्रिंग्स में गैर-एससीआई पात्रों का पता लगाने के लिए एक अच्छी छोटी चाल है, जो कि पायथन 3 में सभी स्ट्रिंग्स से बहुत अधिक है। चूँकि ascii वर्णों को केवल 1 बाइट का उपयोग करके एन्कोड किया जा सकता है, इसलिए किसी भी ascii वर्ण की लंबाई बाइट्स से एन्कोड करने के बाद अपने आकार के लिए सही होगी; जबकि अन्य गैर-एससीआई पात्रों को 2 बाइट्स या 3 बाइट्स के अनुसार एन्कोड किया जाएगा जो उनके आकार में वृद्धि करेगा।
देव

@Far द्वारा सबसे अच्छा उत्तर, लेकिन ऐसा नहीं है कि कुछ वर्ण जैसे… और - ascii की तरह लग सकते हैं, इसलिए यदि आप अंग्रेज़ी पाठ का पता लगाने के लिए इसका उपयोग करना चाहते हैं, तो चेक करने से पहले इस तरह के वर्णों को प्रतिस्थापित करें
Christophe Roussy

1
लेकिन Python2 में यह एक यूनिकोडेनाकोड को फेंक देगा। Py2 और Py3
alvas

2
उन लोगों के लिए जो लंबोदर का उपयोग करने से अपरिचित हैं (जैसा कि मैं जब मैं पहली बार इस उत्तर में आया था) isasciiअब एक समारोह है कि आप एक स्ट्रिंग पास करते हैं: isascii('somestring')== Trueऔर isascii('àéç')==False
rabidang3ls

8
यह सिर्फ सादा फिजूलखर्ची है। यह UTF-8 में एक स्ट्रिंग को एनकोड करता है, जिससे एक पूरे अन्य बाइटस्ट्रिंग का निर्माण होता है। ट्रू पायथन 3 तरीका है try: s.encode('ascii'); return True except UnicodeEncodeError: return False(ऊपर की तरह, लेकिन एन्कोडिंग, जैसा कि पायथन 3 में यूनिकोड हैं)। यह उत्तर भी पायथन 3 में एक त्रुटि उठाता है जब आपके पास सरोगेट होता है (उदाहरण isascii('\uD800')के लिए वापसी के बजाय एक त्रुटि उठाता है False)
आर्टी

71

पायथन 3.7 में नया ( b3232677 )

कोई और अधिक थकाऊ / तारों पर अक्षम ascii चेक, नई निर्मित str/ bytes/ bytearrayविधि - .isascii()अगर तार ascii है की जाँच करेगा।

print("is this ascii?".isascii())
# True

यह एक शीर्ष पर रहने का हकदार है!
सालेक

"\x03".isascii()यह भी सच है। प्रलेखन यह कहता है कि यह जांचता है कि सभी वर्ण कोड प्वाइंट 128 (0-127) से नीचे हैं। यदि आप भी नियंत्रण पात्रों से बचना चाहते हैं, तो आपको आवश्यकता होगी text.isascii() and text.isprintable():। केवल isprintableस्वयं का उपयोग करना भी पर्याप्त नहीं है, क्योंकि यह like (सही ढंग से) प्रिंट करने योग्य जैसे चरित्र पर विचार करेगा, लेकिन यह एससीआई प्रिंट करने योग्य अनुभाग के भीतर नहीं है, इसलिए आपको दोनों की जांच करने की आवश्यकता है यदि आप दोनों चाहते हैं। अभी तक एक और गोटा: रिक्त स्थान को मुद्रण योग्य माना जाता है, टैब और न्यूलाइन्स नहीं हैं।
ल्यूक

19

हाल ही में कुछ इस तरह से भाग गया - भविष्य के संदर्भ के लिए

import chardet

encoding = chardet.detect(string)
if encoding['encoding'] == 'ascii':
    print 'string is in ascii'

जिसका आप उपयोग कर सकते हैं:

string_ascii = string.decode(encoding['encoding']).encode('ascii')

7
बेशक, इसके लिए चार्टड लाइब्रेरी की आवश्यकता है ।
StackExchange saddens dancek

1
हाँ, यद्यपि चारदीवारी अधिकांश प्रतिष्ठानों में डिफ़ॉल्ट रूप से उपलब्ध है
एल्विन

7
chardet केवल इस तरह एक निश्चित संभावना के साथ एन्कोडिंग का अनुमान लगाता है: {'confidence': 0.99, 'encoding': 'EUC-JP'}(जो इस मामले में पूरी तरह से गलत था)
सुजाना

19

विन्सेन्ट मार्खेट्टी के पास सही विचार है, लेकिन str.decodeपाइथन 3 में पदावनत किया गया है। पायथन 3 में आप इसके साथ एक ही टेस्ट कर सकते हैं str.encode:

try:
    mystring.encode('ascii')
except UnicodeEncodeError:
    pass  # string is not ascii
else:
    pass  # string is ascii

ध्यान दें कि आप जो अपवाद पकड़ना चाहते हैं, वह भी इससे बदल गया UnicodeDecodeErrorहै UnicodeEncodeError


ओपी का इनपुट एक बाइटस्ट्रिंग है ( bytesपायथन 3 में टाइप करें जिसकी कोई .encode()विधि नहीं है)। .decode()@Vincent Marchetti का उत्तर सही है
10

@JFSebastian ओपी पूछता है "यह कैसे जांचें कि पायथन में एक स्ट्रिंग ASCII में है?" और बाइट्स यूनिकोड स्ट्रिंग्स द्वारा निर्दिष्ट नहीं करता है। आप कहते हैं कि उसका / उसकी इनपुट एक उपचुनाव है?
drs

1
प्रश्न की तारीख देखें: 'é'उस समय एक उपचुनाव था।
jfs

1
@JFSebastian, ठीक है, इस उत्तर पर विचार करने से इस प्रश्न का उत्तर मिलता है जैसे कि यह आज पूछा गया था, मुझे लगता है कि यह अभी भी मान्य और सहायक है। बहुत कम और कम लोग जवाब
ढूंढते हुए

2
मुझे यह प्रश्न तब मिला जब मैं python3 के लिए एक समाधान खोज रहा था और जल्दी से प्रश्न को पढ़ने से मुझे संदेह नहीं हुआ कि यह python 2 का नमूना था। लेकिन यह उत्तर वास्तव में मददगार था - उत्थान!
जोश 18

17

आपका प्रश्न गलत है; आप जो त्रुटि देखते हैं, वह यह नहीं है कि आपने अजगर को कैसे बनाया, बल्कि बाइट स्ट्रिंग्स और यूनिक स्ट्रिंग्स के बीच एक भ्रम है।

बाइट स्ट्रिंग्स (जैसे "फू", या 'बार', पायथन सिंटैक्स में) ऑक्टेट के अनुक्रम हैं; 0-255 से नंबर। यूनिकोड स्ट्रिंग्स (जैसे u "foo" या u'bar ') यूनिकोड कोड पॉइंट्स के सीक्वेंस हैं; 0-1112064 से नंबर। लेकिन आप चरित्र é में रुचि रखते हैं, जो (आपके टर्मिनल में) एक बहु-बाइट अनुक्रम है जो एकल चरित्र का प्रतिनिधित्व करता है।

इसके बजाय ord(u'é'), यह प्रयास करें:

>>> [ord(x) for x in u'é']

यह बताता है कि "é" कोड बिंदुओं का कौन सा अनुक्रम दर्शाता है। यह आपको [233] दे सकता है, या यह आपको [101, 770] दे सकता है।

chr()इसे उलटने के बजाय , यह है unichr():

>>> unichr(233)
u'\xe9'

यह चरित्र वास्तव में एक एकल या एकाधिक यूनिकोड "कोड पॉइंट" का प्रतिनिधित्व कर सकता है, जो स्वयं या तो अंगूर या वर्णों का प्रतिनिधित्व करता है। यह या तो "एक तीव्र उच्चारण के साथ ई (यानी, कोड बिंदु 233)", या "ई" (कोड बिंदु 101) है, इसके बाद "पिछले चरित्र पर एक तीव्र उच्चारण" (कोड बिंदु 770)। तो यह ठीक उसी चरित्र को पायथन डेटा संरचना के रूप में प्रस्तुत किया जा सकता है u'e\u0301'याu'\u00e9'

अधिकांश समय आपको इस बारे में परवाह नहीं करनी चाहिए, लेकिन यह एक मुद्दा बन सकता है यदि आप एक यूनिकोड स्ट्रिंग से अधिक पुनरावृत्ति कर रहे हैं, क्योंकि यह पुनरावृत्ति कोड बिंदु द्वारा काम करता है, न कि डीकोप्रोजेबल कैरेक्टर द्वारा। दूसरे शब्दों में, len(u'e\u0301') == 2और len(u'\u00e9') == 1। यदि यह आपके लिए मायने रखता है, तो आप उपयोग करके संक्षिप्त और विघटित रूपों के बीच परिवर्तित कर सकते हैंunicodedata.normalize

यूनिकोड शब्दावली इन मुद्दों में से कुछ को समझने के लिए एक उपयोगी मार्गदर्शिका हो सकती है, यह इंगित करके कि कैसे प्रत्येक विशिष्ट शब्द पाठ के प्रतिनिधित्व के एक अलग हिस्से को संदर्भित करता है, जो कई प्रोग्रामर द्वारा महसूस किए जाने की तुलना में कहीं अधिक जटिल है।


3
'é' किसी एक कोड बिंदु का प्रतिनिधित्व नहीं करता है । यह दो कोड पॉइंट (U + 0065 + U + 0301) हो सकते हैं।
जेफ

2
प्रत्येक अमूर्त चरित्र को हमेशा एक कोड बिंदु द्वारा दर्शाया जाता है। हालाँकि, कोड बिंदु एन्कोडिंग योजना के आधार पर कई बाइट्स को एन्कोड किया जा सकता है। यानी, 'यूई' यूटीएफ -8 और यूटीएफ -16 में दो बाइट्स और यूटीएफ -32 में चार बाइट्स हैं, लेकिन यह प्रत्येक मामले में अभी भी एक ही कोड बिंदु है - यू + 00 ई 9।
बेन ब्लैंक

5
@Ben रिक्त: U + 0065 और U + 0301 हैं कोड अंक हैं और वे ऐसा 'ई' जो कर सकते हैं का प्रतिनिधित्व भी U + 00E9 द्वारा प्रस्तुत किया जा। Google "तीव्र उच्चारण का संयोजन"।
जेफ्स

JF U + 0065 और U + 0301 के संयोजन के बारे में 'é' बनाने के लिए सही है, लेकिन यह एक प्रतिवर्ती कार्यात्मक नहीं है। आपको U + 00E9 मिलेगा। विकिपीडिया के अनुसार , ये समग्र कोड बिंदु बैकवर्ड संगतता के लिए उपयोगी हैं
मार्टिन कॉनेनी

1
@ साहित्य - यह इस अर्थ में एक प्रतिवर्ती कार्य है कि आप कोड बिंदु को फिर से सामान्य कर सकते हैं, जो कि एक ही रचित चरित्र का प्रतिनिधित्व करते हुए कोड बिंदुओं के अनुक्रम में एक मिश्रित चरित्र का प्रतिनिधित्व करते हैं। अजगर में आप ऐसा कर सकते हैं: unicodedata.normalize ('NFD', u '\ xe9')।
ग्लिफ जूल

10

यह करने के बारे में कैसे?

import string

def isAscii(s):
    for c in s:
        if c not in string.ascii_letters:
            return False
    return True

5
यदि आप स्ट्रिंग में ASCII वर्ण हैं जो अक्षर नहीं हैं, तो यह विफल हो जाता है। आपके लिए कोड उदाहरण, जिसमें न्यूलाइन, स्पेस, डॉट, अल्पविराम, अंडरस्कोर और कोष्ठक शामिल हैं।
फ्लोरिसला

9

मैंने यह प्रश्न पाया कि कैसे एक स्ट्रिंग का उपयोग / एनकोड / डिकोड करने का प्रयास किया गया है जिसकी एन्कोडिंग मैं निश्चित नहीं था (और उस स्ट्रिंग में विशेष वर्णों से बचने / परिवर्तित करने के लिए कैसे)।

मेरा पहला कदम स्ट्रिंग के प्रकार की जांच करने के लिए होना चाहिए था - मुझे यह महसूस नहीं हुआ कि मैं इसके प्रकार (ओं) से इसके स्वरूपण के बारे में अच्छा डेटा प्राप्त कर सकता हूं। यह उत्तर बहुत मददगार था और मेरे मुद्दों की असली जड़ तक पहुंच गया।

यदि आप एक कठोर और लगातार हो रहे हैं

यूनिकोडडॉफॉर्सेट: 'एससीआई' कोडक 0 स्थान पर 263 बाइट को डिकोड नहीं कर सकता है: ऑर्डिनल रेंज में नहीं (128)

विशेष रूप से जब आप ENCODING कर रहे हों, तो सुनिश्चित करें कि आप यूनिकोड () पहले से ही यूनिकोड- एक स्ट्रिंग को नहीं देख रहे हैं, किसी भयानक कारण से, आपको ascii कोडेक त्रुटियाँ मिलती हैं। ( पायथन किचन रेसिपी भी देखें और पाइथन डॉक्स ट्यूटोरियल इस बात की बेहतर समझ के लिए कि यह कितना भयानक हो सकता है।)

आखिरकार मैंने निर्धारित किया कि मैं जो करना चाहता था वह यह था:

escaped_string = unicode(original_string.encode('ascii','xmlcharrefreplace'))

डिबगिंग में भी उपयोगी utf-8 के लिए मेरी फ़ाइल में डिफ़ॉल्ट कोडिंग सेट कर रहा था (इसे अपनी पायथन फ़ाइल की शुरुआत में डालें):

# -*- coding: utf-8 -*-

यह आपको उनके यूनिकोड से बचने के लिए (यू 'xe0 \ xe9 \ xe7') का उपयोग किए बिना विशेष वर्णों का परीक्षण करने की अनुमति देता है।

>>> specials='àéç'
>>> specials.decode('latin-1').encode('ascii','xmlcharrefreplace')
'&#224;&#233;&#231;'

4

अलेक्जेंडर के समाधान को पायथन 2.6 (और पायथन 3.x में) से सुधारने के लिए आप हेल्पर मॉड्यूल शापों का उपयोग कर सकते हैं। कैसिआई और शापों का उपयोग कर सकते हैं। एससीआई। आईससी () फ़ंक्शन या अन्य अन्य: https://docs.pywon.org/2.6/ पुस्तकालय / curses.ascii.html

from curses import ascii

def isascii(s):
    return all(ascii.isascii(c) for c in s)


2

आप पॉज़िक्स मानक [[: ASCII:]] परिभाषा को स्वीकार करने वाले नियमित अभिव्यक्ति पुस्तकालय का उपयोग कर सकते हैं।


2

strपायथन में एक स्टिंग ( -टाइप) बाइट्स की एक श्रृंखला है। केवल स्ट्रिंग को देखने से बताने का कोई तरीका नहीं है कि क्या बाइट्स की यह श्रृंखला एक एस्की स्ट्रिंग का प्रतिनिधित्व करती है, 8-बिट charset में एक स्ट्रिंग जैसे ISO-8859-1 या UTF-8 या UTF-16 के साथ एन्कोडेड स्ट्रिंग ।

हालाँकि, यदि आप उपयोग किए गए एन्कोडिंग को जानते हैं, तो आप उसे decodeएक यूनिकोड स्ट्रिंग में बदल सकते हैं और फिर यह जांचने के लिए कि क्या वह सीमा से बाहर के वर्ण हैं, की जाँच करने के लिए एक नियमित अभिव्यक्ति (या लूप) का उपयोग करें।


1

@ RogerDahl के उत्तर की तरह लेकिन यह चरित्र वर्ग की उपेक्षा करके find_allया इसके बजाय खोज का उपयोग करके शॉर्ट-सर्किट के लिए अधिक कुशल है match

>>> import re
>>> re.search('[^\x00-\x7F]', 'Did you catch that \x00?') is not None
False
>>> re.search('[^\x00-\x7F]', 'Did you catch that \xFF?') is not None
True

मैं कल्पना करता हूं कि एक नियमित अभिव्यक्ति इसके लिए अच्छी तरह से अनुकूलित है।


0
import re

def is_ascii(s):
    return bool(re.match(r'[\x00-\x7F]+$', s))

ASCII के रूप में एक खाली स्ट्रिंग शामिल करने के लिए, को बदलने +के लिए *


-1

अपने कोड को क्रैश से बचाने के लिए, आप शायद try-exceptइसे पकड़ने के लिए उपयोग करना चाहते हैंTypeErrors

>>> ord("¶")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ord() expected a character, but string of length 2 found

उदाहरण के लिए

def is_ascii(s):
    try:
        return all(ord(c) < 128 for c in s)
    except TypeError:
        return False

यह tryरैपर पूरी तरह से व्यर्थ है। यदि "¶"एक यूनिकोड स्ट्रिंग है, तो ord("¶")काम करेगा, और यदि यह (पायथन 2) नहीं है, for c in sतो इसे बाइट्स में विघटित कर ordदेगा ताकि काम करना जारी रहेगा।
Ry-

-5

मैं निम्नलिखित का उपयोग यह निर्धारित करने के लिए करता हूं कि स्ट्रिंग एससीआई या यूनिकोड है:

>> print 'test string'.__class__.__name__
str
>>> print u'test string'.__class__.__name__
unicode
>>> 

फिर फ़ंक्शन को परिभाषित करने के लिए बस एक सशर्त ब्लॉक का उपयोग करें:

def is_ascii(input):
    if input.__class__.__name__ == "str":
        return True
    return False

4
-1 AARRGGH यह ASCII के रूप में रेंज (128), में सभी वर्णों (c) के साथ व्यवहार कर रहा है !!!
जॉन मैकिन

काम नहीं करता है। निम्नलिखित कॉल करने का प्रयास करें is_ascii(u'i am ascii'):। हालांकि अक्षर और रिक्त स्थान निश्चित रूप से ASCII हैं, फिर भी यह वापस आ जाता है Falseक्योंकि हमने स्ट्रिंग को मजबूर किया unicode
jpmc26
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.