2010-11-29 67 views
10

Je dois diviser une chaîne et extraire les mots séparés par des caractères d'espacement. La source peut être en anglais ou en japonais. Les caractères d'espaces blancs anglais incluent l'onglet et l'espace, et le texte japonais les utilise également. (IIRC, tous les jeux de caractères japonais largement utilisés sont des surensembles de US-ASCII.)Quels sont tous les caractères d'espaces blancs japonais?

Donc l'ensemble de caractères que j'ai besoin d'utiliser pour séparer ma chaîne comprend un espace ASCII normal et une tabulation. Mais, en japonais, il existe un autre caractère d'espace, communément appelé «espace pleine largeur». Selon l'utilitaire Character Viewer de mon Mac, c'est U + 3000 "IDEOGRAPHIC SPACE". C'est (généralement) ce qui se passe lorsqu'un utilisateur appuie sur la barre d'espace tout en tapant en mode de saisie japonais.

Y a-t-il d'autres caractères à prendre en compte?

Je suis en train de traiter des données textuelles soumises par des utilisateurs à qui on a demandé de "séparer les entrées avec des espaces". Cependant, les utilisateurs utilisent une grande variété de systèmes d'exploitation pour ordinateurs et téléphones mobiles pour soumettre ces textes. Nous avons déjà vu que les utilisateurs peuvent ne pas savoir s'ils sont en mode de saisie japonais ou anglais lors de la saisie de ces données. En outre, le comportement de la clé spatiale diffère entre plates-formes et applications même en mode japonais (par exemple, Windows 7 insérera un espace idéographique mais iOS insérera un espace ASCII). Donc ce que je veux, c'est fondamentalement "l'ensemble de tous les caractères qui ressemblent visuellement à un espace et qui peuvent être générés lorsque l'utilisateur appuie sur la touche espace, ou sur la touche tabulation car de nombreux utilisateurs ne connaissent pas la différence un onglet, en japonais et/ou en anglais ".

Y a-t-il une réponse faisant autorité à une telle question?

+1

Aucun langage de programmation avec un support Unicode correct ne devrait-il vous permettre de diviser une chaîne (en utilisant une regex) sur un espace? Par exemple - '/ \ s /' correspond aux caractères espaces en JavaScript (équivalent à '[\ f \ n \ r \ t \ v \ u00A0 \ u2028 \ u2029]'). –

+3

Matt: L'expression rationnelle que vous avez citée est déjà manquante '\ u3000' et l'OP se demande ce qui pourrait manquer. La liste d'espace séparateur Unicode a 18 entrées: http://www.fileformat.info/info/unicode/category/Zs/list.htm – Gabe

+1

Matt: Oui, je souhaite, mais la notion que JavaScript (et, étonnamment, même Ruby) A propos de ce qui constitue un 'espace blanc' générique n'inclut pas le caractère d'espace blanc japonais (s?). Gabe: merci pour ce lien, fouiller manuellement dans mon viewer Unicode je suis tombé sur EM SPACE, FIGURE SPACE et ses amis, mais je n'avais pas rencontré OGHAM SPACE MARK ou MONGOLIAN VOWEL SEPARATOR ... – Mason

Répondre

4

Vous avez besoin de l'onglet ASCII, de l'espace et de l'espace insécable (U + 00A0) et de l'espace pleine largeur, que vous avez correctement identifié comme U + 3000. Vous pourriez éventuellement vouloir des caractères de nouvelle ligne et des espaces verticaux. Si votre entrée est en Unicode (pas Shift-JIS, etc.) alors c'est tout ce dont vous aurez besoin. Il existe d'autres caractères (de contrôle) tels que \ 0 NULL qui sont parfois utilisés comme délimiteurs d'informations, mais ils ne seront pas rendus en tant qu'espace dans le texte d'Asie orientale, c'est-à-dire qu'ils n'apparaîtront pas en tant qu'espace blanc. : Matt Ball a un bon point dans son commentaire, mais, comme son exemple l'illustre, de nombreuses implémentations regex ne traitent pas bien la ponctuation en Asie de l'Est sur toute la largeur. À cet égard, il vaut la peine de mentionner que le string.whitespace de Python ne coupera pas non plus la moutarde.

+0

Je veux vraiment vous croire, parce que cela signifie que j'ai terminé! :) Mais, comment le savez-vous? – Mason

+1

Je travaille tous les jours avec du texte d'une variété de provenances d'Asie de l'Est. dans quel environnement/langage de programmation êtes-vous? Je peux peut-être donner des conseils plus précis. une regex qui fonctionne avec tout dans le lien de Gabe suffirait-elle? – simon

+0

Vous avez raison; Alors que je finissais par écrire une méthode qui traitait de tous les espaces étranges dans le lien de Matt, j'ai également testé manuellement la soumission de 24 combinaisons de plates-formes/applications différentes. Tab, espace, U + 00A0 et U + 3000 étaient tout ce qui se passait dans le monde réel. J'ai donc accepté votre réponse. Merci! – Mason

3

Je viens de trouver votre message. C'est une excellente explication sur la normalisation des caractères Unicode.

http://en.wikipedia.org/wiki/Unicode_equivalence

Je trouve que beaucoup de langages de programmation, comme Python, ont des modules qui peuvent mettre en œuvre ces règles de normalisation des normes Unicode. Pour mes besoins, j'ai trouvé que le code python suivant fonctionne très bien. Il convertit toutes les variantes d'unicode d'espaces blancs dans la plage ASCII. Après la normalisation, une commande regex peut convertir tous les espaces à ascii \ x32: Module

import unicodedata 
# import re 

ucode = u'大変、 よろしくお願い申し上げます。' 

normalized = unicodedata.normalize('NFKC', ucode) 

# old code 
# utf8text = re.sub('\s+', ' ', normalized).encode('utf-8') 

# new code 
utf8text = ' '.join(normalized.encode('utf-8').split()) 

Depuis la première écriture, j'ai appris regex de Python (re) itentifies mal ces caractères blancs et peut provoquer un plantage si rencontré. Il s'avère une méthode plus rapide et plus fiable pour utiliser la fonction .split().