Théorie
Les expressions rationnelles correspondent aux grammaires de type 3 (voir Grammaire formelle) de la hiérarchie de Chomsky ; elles peuvent donc être utilisées pour décrire la morphologie d’une langue.
Expressions rationnelles et Unicode
Les expressions rationnelles ont originellement été utilisées avec les caractères ASCII. Beaucoup de moteurs d’expressions rationnelles peuvent maintenant gérer l’Unicode. Sur plusieurs points, le jeu de caractères codés utilisés ne fait aucune différence, mais certains problèmes surgissent dans l’extension des expressions rationnelles pour Unicode.
Une question est de savoir quel format de représentation interne d’Unicode est supporté. Tous les moteurs d’expressions rationnelles en ligne de commande attendent de l’UTF-8, mais pour les bibliothèques, certaines attendent aussi de l’UTF-8, mais d’autres attendent un jeu codé sur UCS-2 uniquement (voire son extension UTF-16 qui restreint aussi les séquences valides), ou sur UCS-4 uniquement (voire sa restriction normalisée UTF-32).
Une deuxième question est de savoir si l’intégralité de la plage des valeurs d’une version d’Unicode est supportée. Beaucoup de moteurs ne supportent que le Basic Multilingual Plane, c’est-à-dire, les caractères encodables sur 16 bits. Seuls quelques moteurs peuvent (dès 2006) gérer les plages de valeurs Unicode sur 21 bits.
Une troisième question est de savoir comment les constructions ASCII sont étendues à l’Unicode.
- Par exemple, dans les mises en œuvre ASCII, les plages de valeurs de la forme
[x-y]
sont valides quels que soient x et y dans la plage 0x0..0x7F et {{{1}}}. - L’extension naturelle de ces plages de valeurs Unicode changerait simplement l’exigence sur la plage de valeurs [0..0x7F] en exigence sur la plage étendue à 0..0x1FFFFF.
Cependant, en pratique ce n’est souvent pas le cas :
- Certaines mises en œuvre, telles que celle de gawk, ne permettent pas aux plages de valeurs de couvrir plusieurs blocs Unicode. Une plage de valeurs telle que [0x61..0x7F] est valide puisque les deux bornes tombent à l’intérieur du même bloc Basic Latin, comme 0x530..0x560 qui tombe dans le bloc arménien, mais une plage telle que [0x61..0x532] est invalide puisqu’elle est à cheval sur plusieurs blocs Unicode. Cette restriction s’avère très gênante car de nombreuses langues nécessitent des caractères appartenant à des blocs différents, la définition même des blocs étant arbitraire et provenant seulement du processus historique d’allocation et d’évolution de la norme ISO/IEC 10646 (et en conséquence aussi, des évolutions du standard Unicode). Une telle restriction devrait être à terme levée par une amélioration de l’implémentation.
- D’autres moteurs tels que celui de l’éditeur Vim, permettent le chevauchement de blocs mais limitent le nombre de caractères d’une plage à 128, ce qui est encore plus pénalisant car cela ne permet pas de traiter directement certaines écritures, où il faudrait lister un nombre considérable de sous-plages, avec des conséquences importantes sur les performances. Là aussi, des améliorations sont attendues dans l’implémentation pour lever ces restrictions.
Un autre domaine dans lequel des variations existent est l’interprétation des indicateurs d’insensibilité à la casse.
- De tels indicateurs n’affectent que les caractères ASCII ; d’autres affectent tous les caractères (et prennent en compte le mappage de casse soit caractère par caractère dans les implémentations les plus simples, soit au niveau du texte entier dans les implémentations respectant les contraintes de langues, ceci pouvant utiliser les mappages d’un sous-ensemble d’une version donnée d’Unicode, d’autres pouvant utiliser tous les mappages de n’importe quelle version d’Unicode, éventuellement précisable au sein même de l’expression rationnelle).
- Certains moteurs ont deux indicateurs différents, l’un pour ASCII, l’autre pour Unicode.
- Les caractères exacts qui appartiennent aux classes POSIX varient également.
Une autre réponse à Unicode a été l’introduction des classes de caractères pour les blocs Unicode et les propriétés générales des caractères Unicode:
- En Perl et dans la bibliothèque
java.util.regex
de Java, les classes de la forme \p{InX}
valident les caractères du bloc X et \P{InX}
valide le complément. Par exemple, \p{Arabic}
valide n’importe quel caractère de l’écriture arabe (dans l’un quelconque des blocs normalisés d’Unicode/ISO/IEC 10646 où de tels caractères sont présents). - Similairement,
\p{X}
valide n’importe quel caractère ayant la propriété de catégorie générale de caractère X et \P{X}
le complément. Par exemple, \p{Lu}
valide n’importe quel lettre capitale (upper-case letter). - D’autres propriétés que la catégorie générale peuvent être désignées avec la notation
\p{prop=valeur}
et son complément \P{prop=valeur}
, où prop est le code d’une propriété de caractères, et valeur sa valeur attribuée à chaque caractère. - Enfin des extensions ont été proposées pour utiliser un autre opérateur que la seule égalité (ou différence) de valeur de propriété, en utilisant une syntaxe d’expression rationnelle ou une simple alternation pour la valeur.
Notes :
- Certaines propriétés de caractères sont normatives et ne devraient pas dépendre de la version utilisée, c’est le cas des propriétés définies dans ISO/IEC 10646 : le nom normalisé du caractère, le point de code, le nom du bloc où le caractère est codé.
- D’autres propriétés sont standards et correspondent à des propriétés normatives du standard Unicode : ce sont essentiellement les propriétés de base définies dans la table principale de caractères Unicode. En principe, elles sont invariables. C’est le cas des mappages simples de casse (caractère par caractère), ou de la catégorie générale du caractère. Dans bien des cas, ces propriétés ne sont pas adaptées à toutes les langues.
- D’autres propriétés sont informatives, et peuvent faire l’objet de révision d’une version d’Unicode à l’autre : ce sont essentiellement les propriétés définies dans les tables supplémentaires d’Unicode. En particulier elles sont adaptables en fonction de la langue utilisée et désignent par exemple les propriétés de mappages de casse étendus (traitant le texte dans sa globalité), ou les propriétés d’ordonnancement (collation).
- Cependant certaines de ces dernières tables ont acquis le statut de standard (en étant intégrées dans des annexes standards du standard Unicode) et sont même utilisées dans la définition de certaines normes), ou bien d’autres propriétés historiques sont encore maintenues mais d’usage non recommandé. Consulter le standard Unicode pour connaître le statut actuel de ces propriétés.