python कैसे जांचें कि पायथन में एक स्ट्रिंग ASCII में है या नहीं?




string unicode (12)

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

>>> 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

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

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

जांचने का कोई और तरीका है?


@ रोजरडाहल के answer लेकिन चरित्र वर्ग को अस्वीकार करके और 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

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


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

पायथन में एक स्टिंग ( str टाइप) बाइट्स की एक श्रृंखला है। केवल स्ट्रिंग को देखने से कहने का कोई तरीका नहीं है कि बाइट्स की यह श्रृंखला एएससीआई स्ट्रिंग का प्रतिनिधित्व करती है, 8-बिट वर्णमाला में एक स्ट्रिंग आईएसओ -885 9 -1 या यूटीएफ -8 या यूटीएफ -16 के साथ एन्कोडेड स्ट्रिंग या जो भी हो ।

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


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

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

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


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

from curses import ascii

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

import re

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

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


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

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

ord(u'é') बजाय, इसे आजमाएं:

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

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

unichr() को इसके विपरीत करने के बजाय, unichr() :

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

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

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

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


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

import string

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

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

import chardet

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

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

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

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

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

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

पायथन में एक स्ट्रिंग में '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"




ascii