web-dev-qa-db-fra.com

Python: Vérifiez si une chaîne contient du caractère chinois?

Une chaîne peut-être ça

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

ou ca

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

Comment savoir si la première chaîne contient chinois ?

Je trouve cette réponse peut-être utile: Trouver tout le texte chinois dans une chaîne en utilisant Python et Regex

mais ça n'a pas marché:

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

La chaîne correspondante doit également être unicode

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

Si vous voulez simplement savoir s'il y a un caractère chinois dans votre chaîne, vous n'avez pas besoin de re.findall, utilisation re.search et le fait que les objets correspondants soient véridiques.

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

Et pour ceux d'entre nous qui ne se soucient pas de 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]
... 
上
海
虹
桥

Edit: pour la liste complète des caractères chinois, ce lien SO vaut la peine d'être examiné car la plage U + 4E00..U + 9FFF n'est pas complète. Quelle est la plage complète pour le chinois caractères en Unicode?

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

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

Vous devez décoder l'entrée pour la rendre unicode.

ou

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

En utilisant ces plages de points de code , nous pouvons écrire un is_cjk fonction:

# 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 nous pouvons ensuite utiliser pour traiter le texte, en utilisant des fonctions comme filter, any, all et map pour traiter le texte caractère par caractère, ou composez des fonctions plus complexes:

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)) # '上海虹桥'

Notez que les gammes CJK comprendront non seulement des caractères chinois, mais peuvent également inclure des caractères coréens et japonais. Pour une utilisation plus complexe, essayez une bibliothèque dédiée comme cjklib .

1
9999years

'' est un bytestring sur Python 2. Soit ajoutez from __future__ import unicode_literals en haut du module ou utilisez des littéraux unicode: u'':

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

Dans python 3.6 j'ai utilisé ceci

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

Selon cette question , la plage doit être [\u2E80-\u2FD5\u3190-\u319f\u3400-\u4DBF\u4E00-\u9FCC]

0
Kevin He