Python: ¿Comprobar si una cadena contiene caracteres chinos?

Una cuerda tal vez esto

ipath= "./data/NCDC/上海/虹桥/9705626661750dat.txt" 

o esto

 ipath = './data/NCDC/ciampino/6240476818161dat.txt' 

¿Cómo sé que la primera cadena contiene chino ?

Me parece útil esta respuesta: Encuentre todo el texto chino en una cadena usando Python y Regex

pero no funcionó:

 import re ipath= "./data/NCDC/上海/虹桥/9705626661750dat.txt" re.findall(ur'[\u4e00-\u9fff]+', ipath) # => [] 

La cadena coincidente también debe ser unicode

 >>> import re >>> ipath= u"./data/NCDC/上海/虹桥/9705626661750dat.txt" >>> re.findall(ur'[\u4e00-\u9fff]+', ipath) [u'\u4e0a\u6d77', u'\u8679\u6865'] 

Si solo quieres saber si hay un carácter chino en tu cadena, no necesitas re.findall , usa re.search y el hecho de que los objetos coinciden son veraces.

 >>> import re >>> ipath= u'./data/NCDC/上海/虹桥/9705626661750dat.txt' >>> ipath2 = u'./data/NCDC/ciampino/6240476818161dat.txt' >>> for x in (ipath, ipath2): ... if re.search(u'[\u4e00-\u9fff]', x): ... print 'found chinese character in ' + x ... found chinese character in ./data/NCDC/上海/虹桥/9705626661750dat.txt 

Y para aquellos de nosotros que no nos importa re :

 >>> ipath= u"./data/NCDC/上海/虹桥/6240476818161dat.txt" >>> for i in range(len(ipath)): ... if ipath[i] > u'\u4e00' and ipath[i] < u'\u9fff': ... print ipath[i] ...上海虹桥 

Edición: para ver la lista completa de caracteres chinos, vale la pena mirar este enlace SO ya que el rango U + 4E00..U + 9FFF no está completo. ¿Cuál es el rango completo para los caracteres chinos en Unicode?

 import re ipath= raw_input() print re.findall(ur'[\u4e00-\u9fff]+', ipath.decode("utf-8")) 

Salida: ./data/NCDC/上海/虹桥/9705626661750dat.txt [u'\u4e0a\u6d77', u'\u8679\u6865']

Necesitas decodificar la entrada para hacerla unicode.

o

  import re ipath= unicode(raw_input(),encoding="utf-8") print re.findall(ur'[\u4e00-\u9fff]+', ipath) 

'' es un bytestring en Python 2. Agregue from __future__ import unicode_literals en la parte superior del módulo o use literales de unicode: u'' :

 >>> import re >>> ipath= u"./data/NCDC/上海/虹桥/9705626661750dat.txt" >>> re.findall(ur'[\u4e00-\u9fff]+', ipath) [u'\u4e0a\u6d77', u'\u8679\u6865'] 

En Python 3.6 usé esto.

 def find_china_symbols(text): """ :param text: input text with wrong symbols :return: True if incorrect char exists in text """ for char in text: if ord(char) > 10000: print(char, ': ', ord(char)) return True 

De acuerdo con esta pregunta , el rango debe ser [\u2E80-\u2FD5\u3190-\u319f\u3400-\u4DBF\u4E00-\u9FCC]

Usando estos rangos de punto de código , podemos escribir una función is_cjk :

 # list of cjk codepoint ranges # tuples indicate the bottom and top of the range, inclusive cjk_ranges = [ ( 0x4E00, 0x62FF), ( 0x6300, 0x77FF), ( 0x7800, 0x8CFF), ( 0x8D00, 0x9FCC), ( 0x3400, 0x4DB5), (0x20000, 0x215FF), (0x21600, 0x230FF), (0x23100, 0x245FF), (0x24600, 0x260FF), (0x26100, 0x275FF), (0x27600, 0x290FF), (0x29100, 0x2A6DF), (0x2A700, 0x2B734), (0x2B740, 0x2B81D), (0x2B820, 0x2CEAF), (0x2CEB0, 0x2EBEF), (0x2F800, 0x2FA1F) ] def is_cjk(char): char = ord(char) for bottom, top in cjk_ranges: if char >= bottom and char <= top: return True return False 

Que luego podemos usar para procesar texto, usando funciones como filter , any , all y map para procesar el texto carácter por carácter, o componer funciones más complejas:

 txt = "./data/NCDC/上海/虹桥/9705626661750dat.txt" txt_sanitized = "./data/NCDC/9705626661750dat.txt" any(map(is_cjk, txt)) # True any(map(is_cjk, txt_sanitized)) # False ''.join(filter(is_cjk, txt)) # '上海虹桥' 

Tenga en cuenta que los rangos CJK incluirán no solo caracteres chinos, sino que también pueden incluir caracteres coreanos y japoneses. Para un uso más complejo, pruebe una biblioteca dedicada como cjklib .