Domanda

Voglio verificare se una stringa è in ASCII o meno.

Sono a conoscenza di ord () , tuttavia quando provo ord ('é') , ho TypeError: ord () mi aspettavo un carattere, ma è stata trovata una stringa di lunghezza 2 . Ho capito che è causato dal modo in cui ho creato Python (come spiegato in ord () della documentazione ).

C'è un altro modo per verificare?

È stato utile?

Soluzione

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

Altri suggerimenti

Penso che tu non stia facendo la domanda giusta--

Una stringa in python non ha proprietà corrispondenti a 'ascii', utf-8 o qualsiasi altra codifica. La fonte della tua stringa (sia che tu la legga da un file, l'input da una tastiera, ecc.) Potrebbe aver codificato una stringa unicode in ascii per produrre la tua stringa, ma è lì che devi cercare una risposta.

Forse la domanda che puoi porre è: " È questa stringa il risultato della codifica di una stringa unicode in ascii? " - A questo puoi rispondere     provando:

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"

Python 3 vie:

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

Per verificare, passare la stringa di test:

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

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

Novità in Python 3.7 ( bpo32677 )

Niente più controlli ASCII stancanti / inefficienti sulle stringhe, nuovo metodo str / byte incorporato / bytearray - .isascii () verificherà se le stringhe sono ascii .

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

Mi sono imbattuto in qualcosa di simile di recente - per riferimento futuro

import chardet

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

che puoi usare con:

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

La tua domanda non è corretta; l'errore che vedi non è il risultato di come hai creato Python, ma di una confusione tra stringhe di byte e stringhe unicode.

Le stringhe di byte (ad es. " foo " ;, o 'bar', nella sintassi di Python) sono sequenze di ottetti; numeri da 0 a 255. Le stringhe Unicode (ad esempio u "pippo" o "barra") sono sequenze di punti di codice unicode; numeri da 0-1112064. Ma sembra che tu sia interessato al carattere & # 233 ;, che (nel tuo terminale) è una sequenza multi-byte che rappresenta un singolo carattere.

Invece di ord (u '& # 233;') , prova questo:

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

Questo ti dice quale sequenza di punti di codice " & # 233; " rappresenta. Potrebbe darti [233] o potrebbe darti [101, 770].

Invece di chr () per invertire questo, c'è unichr () :

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

Questo personaggio può effettivamente essere rappresentato con un singolo o multiplo unicode "punti di codice", che a loro volta rappresentano grafemi o caratteri. È o "e con un accento acuto (cioè il punto di codice 233)", oppure "e"; (codice punto 101), seguito da "un accento acuto sul carattere precedente" (codice punto 770). Quindi questo stesso identico personaggio può essere presentato come struttura di dati Python u'e \ u0301 ' o u' \ u00e9 '.

Il più delle volte non dovresti preoccupartene, ma può diventare un problema se stai iterando su una stringa unicode, poiché l'iterazione funziona per punto di codice, non per carattere scomponibile. In altre parole, len (u'e \ u0301 ') == 2 e len (u' \ u00e9 ') == 1 . Se questo è importante per te, puoi convertire tra moduli composti e decomposti utilizzando unicodedata.normalize .

Glossario Unicode può essere una guida utile per comprendere alcuni di questi problemi, indicando come ciascuno di essi termine si riferisce a una parte diversa della rappresentazione del testo, che è molto più complicata di quanto molti programmatori realizzino.

Che ne dici di fare questo?

import string

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

Vincent Marchetti ha l'idea giusta, ma str.decode è stato deprecato in Python 3. In Python 3 puoi fare lo stesso test con str.encode :

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

Nota che anche l'eccezione che vuoi catturare è cambiata da UnicodeDecodeError a UnicodeEncodeError .

Ho trovato questa domanda mentre provavo a determinare come usare / codificare / decodificare una stringa di cui non ero sicuro (e come sfuggire / convertire caratteri speciali in quella stringa).

Il mio primo passo avrebbe dovuto essere quello di controllare il tipo di stringa. Non mi ero reso conto che avrei potuto ottenere buoni dati sulla sua formattazione dai tipi. Questa risposta è stata molto utile e ha raggiunto la vera radice dei miei problemi.

Se stai diventando scortese e persistente

  

UnicodeDecodeError: il codec 'ascii' non può decodificare il byte 0xc3 in posizione 263: ordinale non nell'intervallo (128)

in particolare quando stai ENCODING, assicurati di non provare a unicode () una stringa che è già unicode - per qualche motivo terribile, ricevi errori di codec ASCII. (Vedi anche la Ricetta Python Kitchen e la documenti Python tutorial per una migliore comprensione di quanto possa essere terribile.)

Alla fine ho deciso che quello che volevo fare era questo:

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

Anche utile nel debug è stato impostare la codifica predefinita nel mio file su utf-8 (mettilo all'inizio del tuo file python):

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

Ciò ti consente di testare caratteri speciali ('& # 224; & # 233; & # 231;') senza dover usare le loro escape unicode (u '\ xe0 \ xe9 \ xe7').

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

Per migliorare la soluzione di Alexander da Python 2.6 (e in Python 3.x) puoi usare il modulo helper curses.ascii e usare la funzione curses.ascii.isascii () o altro: 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)

È possibile utilizzare la libreria di espressioni regolari che accetta la definizione standard [[: ASCII:]] di Posix.

Una puntura ( str -type) in Python è una serie di byte. Non c'è alcun modo di dire semplicemente osservando la stringa se questa serie di byte rappresenta una stringa ASCII, una stringa in un set di caratteri a 8 bit come ISO-8859-1 o una stringa codificata con UTF- 8 o UTF-16 o altro.

Tuttavia, se conosci la codifica utilizzata, puoi decodificare lo str in una stringa unicode e quindi utilizzare un'espressione regolare (o un ciclo) per verificare se contiene caratteri al di fuori dell'intervallo sono preoccupati per.

Per evitare arresti anomali del codice, potresti voler usare un try-tranne per catturare TypeErrors

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

Ad esempio

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

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

Per includere una stringa vuota come ASCII, cambia + in * .

, s))

Per includere una stringa vuota come ASCII, cambia + in * .

Uso quanto segue per determinare se la stringa è ASCII o Unicode:

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

Quindi basta usare un blocco condizionale per definire la funzione:

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