JavaRush /Blog Java /Random-FR /Expressions régulières en Java, partie 2

Expressions régulières en Java, partie 2

Publié dans le groupe Random-FR
Nous présentons à votre attention une traduction d'un petit guide des expressions régulières en Java, rédigé par Jeff Friesen pour le site javaworld . Pour faciliter la lecture, nous avons divisé l'article en plusieurs parties. Expressions régulières en Java, partie 2 - 1Expressions régulières en Java, partie 1
Fusionner plusieurs plages
Vous pouvez fusionner plusieurs plages en une seule classe de caractères en les plaçant côte à côte. Par exemple, la classe [a-zA-Z]fait correspondre tous les caractères alphabétiques latins en minuscules ou en majuscules.

Fusionner plusieurs plages

Vous pouvez fusionner plusieurs plages en une seule classe de caractères en les plaçant côte à côte. Par exemple, la classe [a-zA-Z]fait correspondre tous les caractères alphabétiques latins en minuscules ou en majuscules.

Combiner des classes de personnages

Une union de classes de caractères se compose de plusieurs classes de caractères imbriquées et correspond à tous les caractères de l'union résultante. Par exemple, la classe [a-d[m-p]]fait correspondre les caractères de aà det de mà p. Prenons l'exemple suivant : java RegexDemo [ab[c-e]] abcdef Cet exemple recherchera les caractères a, b, c, det e, pour lesquels il y a des correspondances dansabcdef :
regex = [ab[c-e]]
input = abcdef
Found [a] starting at 0 and ending at 0
Found [b] starting at 1 and ending at 1
Found [c] starting at 2 and ending at 2
Found [d] starting at 3 and ending at 3
Found [e] starting at 4 and ending at 4

Intersection des classes de caractères

L'intersection des classes de caractères est constituée de caractères communs à toutes les classes imbriquées et correspond uniquement aux caractères communs. Par exemple, la classe [a-z&&[d-f]]correspond aux caractères d, eet f. Prenons l'exemple suivant : java RegexDemo "[aeiouy&&[y]]" party Notez que sur mon système d'exploitation Windows, les guillemets doubles sont requis car le shell de commande les traite &comme un séparateur de commande. Cet exemple ne trouvera que le caractère yqui correspond àparty :
regex = [aeiouy&&[y]]
input = party
Found [y] starting at 4 and ending at 4

Soustraire des classes de caractères

La soustraction des classes de caractères comprend tous les caractères à l'exception de ceux contenus dans les classes de caractères imbriquées et correspond uniquement aux caractères restants. Par exemple, la classe [a-z&&[^m-p]]recherche les caractères de aà let de qà z: java RegexDemo "[a-f&&[^a-c]&&[^e]]" abcdefg Cet exemple trouvera les caractères det fpour lesquels il y a des correspondances dans abcdefg:
regex = [a-f&&[^a-c]&&[^e]]
input = abcdefg
Found [d] starting at 3 and ending at 3
Found [f] starting at 5 and ending at 5

Classes de caractères prédéfinies

Certaines classes de caractères apparaissent assez fréquemment dans les expressions régulières pour justifier l'utilisation d'une notation abrégée. La classe Patternpropose des classes de caractères prédéfinies telles que de telles abréviations. Vous pouvez les utiliser pour simplifier vos expressions régulières et minimiser les erreurs de syntaxe. Il existe plusieurs catégories de classes de caractères prédéfinies : java.lang.Characterpropriétés standard, POSIX et Unicode telles que script, bloc, catégorie et binaire. La liste suivante affiche uniquement la catégorie des classes standards :
  • \d: Nombre. Équivalent [0-9].
  • \D: Caractère non numérique. Équivalent [^0-9].
  • \s: Caractère d'espacement. Équivalent [ \t\n\x0B\f\r].
  • \S: Pas un caractère d'espacement. Équivalent [^\s].
  • \w: Symbole formant un mot. Équivalent [a-zA-Z_0-9].
  • \W: Pas un caractère formant un mot. Équivalent [^\w].
L'exemple suivant utilise une classe de caractères prédéfinie \wpour décrire tous les caractères de mot dans le texte d'entrée : java RegexDemo \w "aZ.8 _" Examinez attentivement les résultats d'exécution suivants, qui montrent que les points et les espaces ne sont pas considérés comme des caractères de mot :
regex = \w
input = aZ.8 _
Found [a] starting at 0 and ending at 0
Found [Z] starting at 1 and ending at 1
Found [8] starting at 3 and ending at 3
Found [_] starting at 5 and ending at 5
Séparateurs de lignes
La documentation du SDK de classe Patterndécrit le métacaractère point comme une classe de caractères prédéfinie qui correspond à n'importe quel caractère à l'exception des séparateurs de ligne (séquences d'un ou deux caractères marquant la fin d'une ligne). L'exception est le mode dotall (dont nous parlerons ensuite), dans lequel les points correspondent également aux séparateurs de lignes. La classe Patterndistingue les séparateurs de lignes suivants :
  • caractère de retour chariot (\r );
  • caractère de nouvelle ligne (symbole permettant d'avancer le papier d'une ligne) ( \n);
  • un caractère de retour chariot immédiatement suivi d'un caractère de nouvelle ligne ( \r\n) ;
  • caractère de la ligne suivante (\u0085 );
  • caractère séparateur de ligne (\u2028 );
  • symbole de séparation de paragraphe ( \u2029)

Groupes capturés

Le groupe de capture est utilisé pour enregistrer le jeu de caractères trouvé pour une utilisation ultérieure lors de la recherche par modèle. Cette construction est une séquence de caractères entourés de métacaractères par parenthèses ( ( )). Tous les personnages du groupe capturé sont considérés comme un tout lors de la recherche par modèle. Par exemple, le groupe de capture ( Java) combine les lettres J, aet en une seule unité. Ce groupe de capture trouve toutes les occurrences du modèle dans le texte saisi. A chaque correspondance, les caractères stockés précédents sont remplacés par les suivants. Les groupes capturés peuvent être imbriqués dans d'autres groupes capturés. Par exemple, dans une expression régulière, un groupe est imbriqué dans un groupe . Chaque groupe de capture imbriqué ou non se voit attribuer un numéro, commençant à 1, et la numérotation va de gauche à droite. Dans l'exemple précédent, les correspondances capturent le numéro de groupe 1 et les correspondances capturent le numéro de groupe 2. Dans l'expression régulière , les correspondances capturent le numéro de groupe 1 et les correspondances capturent le numéro de groupe 2. Les correspondances stockées par les groupes de capture sont accessibles ultérieurement à l'aide de références arrière. Spécifiée sous la forme d'un caractère barre oblique inverse suivi d'un caractère numérique correspondant au numéro du groupe en cours de capture, la référence arrière permet de faire référence à des caractères du texte capturé par le groupe. Avoir un backlink amène le comparateur à se référer au résultat de recherche stocké du groupe capturé en fonction du numéro qu'il contient, puis à utiliser les caractères de ce résultat pour tenter une recherche plus approfondie. L'exemple suivant montre l'utilisation d'une référence arrière pour rechercher des erreurs grammaticales dans un texte : Cet exemple utilise une expression régulière pour rechercher une erreur grammaticale suivie immédiatement par un mot en double dans le texte saisi . Cette expression régulière spécifie deux groupes à capturer : le numéro 1 – , correspondant à et le numéro 2 – , correspondant au caractère espace suivi de . La référence arrière permet de revisiter le résultat stocké du groupe numéro 2 afin que le comparateur puisse rechercher la deuxième occurrence d'un espace suivi de , immédiatement après la première occurrence d'un espace et . Les résultats du matcheur sont les suivants : vaJavaJava(Java( language))(language)(Java)(Java( language))(language)(a)(b)(a)(b)Expressions régulières en Java, parties 2 - 2java RegexDemo "(Java( language)\2)" "The Java language language"(Java( language)\2)languageJava"The Java language language"(Java( language)\2)Java language language(language)language\2languagelanguageRegexDemo
regex = (Java( language)\2)
input = The Java language language
Found [Java language language] starting at 4 and ending at 25

Correspondants aux limites

Parfois, vous devez effectuer une correspondance de modèle au début d'une ligne, aux limites des mots, à la fin du texte, etc. Vous pouvez le faire en utilisant l'un des class Edge Matchers Pattern, qui sont des constructions d'expressions régulières qui recherchent des correspondances aux emplacements suivants :
  • ^: Début de ligne ;
  • $: Fin de ligne;
  • \b: Limite de mot ;
  • \B: Limite du pseudo-mot ;
  • \A: Début du texte ;
  • \G: Fin du match précédent ;
  • \Z: Fin du texte, sans compter le séparateur de ligne final (si présent) ;
  • \z: Fin du texte
L'exemple suivant utilise le ^métacaractère de correspondance de limites pour rechercher les lignes commençant par The, suivi de zéro ou plusieurs caractères de mot : java RegexDemo "^The\w*" Therefore Le caractère ^spécifie que les trois premiers caractères du texte saisi doivent correspondre aux caractères de modèle consécutifs T, het e, qui peuvent être suivis de n'importe quel nombre. de symboles formant des mots. Voici le résultat de l'exécution :
regex = ^The\w*
input = Therefore
Found [Therefore] starting at 0 and ending at 8
Que se passe-t-il si vous modifiez la ligne de commande en java RegexDemo "^The\w*" " Therefore"? Aucune correspondance ne sera trouvée car Thereforele texte saisi est précédé d'un caractère espace.

Correspondances de longueur nulle

Parfois, lorsque vous travaillez avec des Edge Matchers, vous rencontrerez des correspondances de longueur nulle. Совпадение нулевой длиныest une correspondance qui ne contient aucun caractère. Ils peuvent apparaître dans un texte de saisie vide, au début du texte de saisie, après le dernier caractère du texte de saisie et entre deux caractères quelconques du texte de saisie. Les correspondances de longueur nulle sont faciles à reconnaître car elles commencent et se terminent toujours à la même position. Prenons l'exemple suivant : java RegExDemo \b\b "Java is" cet exemple recherche deux limites de mots consécutives et les résultats ressemblent à ceci :
regex = \b\b
input = Java is
Found [] starting at 0 and ending at -1
Found [] starting at 4 and ending at 3
Found [] starting at 5 and ending at 4
Found [] starting at 7 and ending at 6
Nous voyons plusieurs correspondances de longueur nulle dans les résultats. Les positions de fin ici sont une de moins que les positions de départ, puisque RegexDemoje l'ai spécifié dans le code source du listing 1 end() – 1. Expressions régulières en Java, parties 2 à 3

Quantificateurs

Un quantificateur est une construction d'expression régulière qui associe explicitement ou implicitement un modèle à une valeur numérique. Cette valeur numérique détermine combien de fois rechercher le modèle. Les quantificateurs sont divisés en gourmands, paresseux et super gourmands :
  • Le quantificateur glouton ( ?, *ou +) est conçu pour trouver la correspondance la plus longue. Puis-je demander X? pour trouver une ou moins d'occurrences X, X*pour trouver zéro ou plusieurs occurrences X, X+pour trouver une ou plusieurs occurrences X, X{n}pour trouver ndes occurrences X, X{n,}pour trouver au moins (et éventuellement plus) nd'occurrences , Xet X{n,m}pour trouver au moins nmais pas plus md'occurrences X.
  • Le quantificateur paresseux ( ??, *?ou +?) est conçu pour trouver la correspondance la plus courte. Vous pouvez spécifier X??de rechercher une ou plusieurs occurrences de X,X* ? pour trouver zéro ou plusieurs occurrences X, X+?pour trouver une ou plusieurs occurrences X, X{n}?pour trouver ndes occurrences X, X{n,}?pour trouver au moins (et éventuellement plus) nd'occurrences X, et X{n,m}?pour trouver au moins nmais pas plus md'occurrences X.
  • Le quantificateur super-gourmand ( ?+, *+ou ++) est similaire au quantificateur glouton, sauf que le quantificateur super-gourmand ne fait qu'une seule tentative pour trouver la correspondance la plus longue, tandis que le quantificateur glouton peut faire plusieurs tentatives. Peut être configuré X?+pour rechercher une ou moins d'occurrences X, X*+pour rechercher zéro ou plusieurs occurrences X, X++pour rechercher une ou plusieurs occurrences X, X{n}+pour rechercher ndes occurrences de X, X{n,}+pour trouver au moins (et éventuellement plus) nd'occurrences Xet X{n,m}+ pour trouver au moins nmais pas plus d' moccurrences . X.
L'exemple suivant illustre l'utilisation du quantificateur glouton : java RegexDemo .*ox "fox box pox" Voici les résultats :
regex = .*ox
input = fox box pox
Found [fox box pox] starting at 0 and ending at 10
Le quantificateur glouton ( .*) trouve la plus longue séquence de caractères se terminant par ox. Il consomme l'intégralité du texte saisi, puis revient en arrière jusqu'à ce qu'il détecte que le texte saisi se termine par ces caractères. Considérons maintenant le quantificateur paresseux : java RegexDemo .*?ox "fox box pox" ses résultats :
regex = .*?ox
input = fox box pox
Found [fox] starting at 0 and ending at 2
Found [ box] starting at 3 and ending at 6
Found [ pox] starting at 7 and ending at 10
Le quantificateur paresseux ( .*?) trouve la séquence la plus courte de caractères se terminant par ox. Il commence par une chaîne vide et consomme progressivement des caractères jusqu'à ce qu'il trouve une correspondance. Et continue ensuite à travailler jusqu'à ce que le texte saisi soit épuisé. Enfin, regardons le quantificateur super-gourmand : java RegexDemo .*+ox "fox box pox" Et voici ses résultats :
regex = .*+ox
input = fox box pox
Le quantificateur extra-gourmand ( .*+) ne trouve pas de correspondance car il consomme tout le texte saisi et il ne reste plus rien à trouver oxà la fin de l'expression régulière. Contrairement au quantificateur glouton, le quantificateur super gourmand ne revient pas en arrière.

Correspondances de longueur nulle

Parfois, lorsque vous travaillez avec des quantificateurs, vous rencontrerez des correspondances de longueur nulle. Par exemple, l'utilisation du quantificateur glouton suivant entraîne plusieurs correspondances de longueur nulle : java RegexDemo a? abaa Les résultats de l'exécution de cet exemple :
regex = a?
input = abaa
Found [a] starting at 0 and ending at 0
Found [] starting at 1 and ending at 0
Found [a] starting at 2 and ending at 2
Found [a] starting at 3 and ending at 3
Found [] starting at 4 and ending at 3
Il y a cinq correspondances dans les résultats d'exécution. Bien que les premier, troisième et quatrième soient assez attendus (ils correspondent aux positions de trois lettres adans abaa), le deuxième et le cinquième risquent de vous surprendre. Il semble qu’ils indiquent ce qui acorrespond bà la fin du texte, mais en réalité ce n’est pas le cas. L'expression régulière a?ne recherche pas bà la fin du texte. Il recherche la présence ou l'absence a. Lorsqu'il a?ne trouve pas a, il le signale comme une correspondance de longueur nulle.

Expressions de drapeau imbriquées

Les matchers font des hypothèses par défaut qui peuvent être remplacées lors de la compilation de l'expression régulière dans un modèle. Nous discuterons de cette question plus tard. Une expression régulière vous permet de remplacer n'importe quelle valeur par défaut à l'aide d'une expression d'indicateur imbriquée. Cette construction d'expression régulière est spécifiée sous la forme d'un métacaractère composé de parenthèses autour d'un métacaractère de point d'interrogation ( ?), suivi d'une lettre latine minuscule. La classe Patterncomprend les expressions d'indicateur imbriquées suivantes :
  • (?i): Active la correspondance de modèle insensible à la casse. Par exemple, lors de l'utilisation d'une commande, java RegexDemo (?i)tree Treehousela séquence de caractères Treecorrespond au modèle tree. La valeur par défaut est la recherche de modèles sensibles à la casse.
  • (?x): Permet l'utilisation de caractères d'espacement et de commentaires commençant par le métacaractère dans le modèle #. Le matcher ignorera les deux. Par exemple, pour java RegexDemo ".at(?x)#match hat, cat, and so on" matterune séquence de caractères matcorrespond au modèle .at. Par défaut, les espaces et les commentaires ne sont pas autorisés et le comparateur les traite comme des caractères impliqués dans la recherche.
  • (?s): Active le mode dotall, dans lequel le métacaractère point correspond aux séparateurs de ligne en plus de tout autre caractère. Par exemple, la commande java RegexDemo (?s). \ntrouvera un caractère de nouvelle ligne. La valeur par défaut est l'opposé de dotall : aucun séparateur de ligne ne sera trouvé. Par exemple, la commande Java RegexDemo . \nne trouvera pas de caractère de nouvelle ligne.
  • (?m): Active le mode multiligne, où il ^fait correspondre le début et $la fin de chaque ligne. Par exemple, java RegexDemo "(?m)^abc$" abc\nabcrecherche les deux séquences dans le texte saisi abc. Par défaut, le mode sur une seule ligne est utilisé : ^correspond au début de l'intégralité du texte saisi et $correspond à la fin de celui-ci. Par exemple, java RegexDemo "^abc$" abc\nabcrenvoie une réponse indiquant qu'il n'y a aucune correspondance.
  • (?u): Active l'alignement de la casse sensible à Unicode. Cet indicateur, lorsqu'il est utilisé conjointement avec (?i), permet une correspondance de modèle insensible à la casse conformément à la norme Unicode. Le paramètre par défaut consiste à rechercher uniquement les caractères sensibles à la casse et US-ASCII.
  • (?d): Active le mode chaîne de style Unix, où le comparateur reconnaît les métacaractères dans le contexte ., ^et $uniquement le séparateur de ligne \n. La valeur par défaut est le mode chaîne de style non Unix : le matcher reconnaît, dans le contexte des métacaractères ci-dessus, tous les délimiteurs de ligne.
Les expressions de drapeau imbriquées ressemblent à des groupes capturés car leurs caractères sont entourés de métacaractères entre parenthèses. Contrairement aux groupes capturés, les expressions d'indicateur imbriquées sont un exemple de groupes non capturés, qui sont une construction d'expression régulière qui ne capture pas les caractères de texte. Ils sont définis comme des séquences de caractères entourées de métacaractères de parenthèses.
Spécification de plusieurs expressions d'indicateur imbriquées
Il est possible de spécifier plusieurs expressions de drapeau imbriquées dans une expression régulière en les plaçant côte à côte ( (?m)(?i))) ou en plaçant les lettres qui les définissent séquentiellement ( (?mi)).

Conclusion

Comme vous l'avez probablement déjà réalisé, les expressions régulières sont extrêmement utiles et le deviennent encore plus à mesure que vous maîtrisez les nuances de leur syntaxe. Jusqu'à présent, je vous ai présenté les bases des expressions régulières et du Pattern. Dans la deuxième partie, nous examinerons plus en détail l'API Regex et explorerons les méthodes de Pattern, Matcheret PatternSyntaxException. Je vais également vous montrer deux applications pratiques de l'API Regex que vous pouvez utiliser immédiatement dans vos programmes. Expressions régulières en Java, partie 3 Expressions régulières en Java, partie 4 Expressions régulières en Java, partie 5
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION