Simplifiez les tâches de programmation courantes avec l'API Regex
Dans les parties 1 et 2 de cet article, vous avez découvert les expressions régulières et l'API Regex. Vous avez découvert le coursPattern
et parcouru des exemples illustrant les constructions d'expressions régulières, de la simple correspondance de modèles utilisant des chaînes littérales à la correspondance plus complexe utilisant des plages, des comparateurs de limites et des quantificateurs. Dans cette partie et les suivantes, nous examinerons les questions non abordées dans la première partie, nous étudierons les méthodes correspondantes des classes Pattern
, Matcher
et PatternSyntaxException
. Vous apprendrez également deux utilitaires qui utilisent des expressions régulières pour faciliter les problèmes de programmation courants. Le premier extrait les commentaires du code pour la documentation. La seconde est une bibliothèque de code réutilisable conçue pour effectuer une analyse lexicale – un composant essentiel des assembleurs, compilateurs et logiciels similaires.
TÉLÉCHARGEMENT DU CODE SOURCE
Vous pouvez obtenir tout le code source (créé par Jeff Friesen pour JavaWorld) pour les applications de démonstration de cet article à partir d'ici .Apprendre l'API Regex
Pattern
, Matcher
et PatternSyntaxException
sont les trois classes qui composent l'API Regex. Chacun d'eux fournit des méthodes qui vous permettent d'utiliser des expressions régulières dans votre code.
Méthodes de la classe Pattern
Une instance d'une classePattern
est une expression régulière compilée, également appelée modèle. Les expressions régulières sont compilées pour améliorer les performances des opérations de correspondance de modèles. Les méthodes statiques suivantes prennent en charge la compilation.
Pattern compile(String regex)
compile le contenuregex
dans une représentation intermédiaire stockée dans un nouveau fichierPattern
. Cette méthode renvoie une référence à un objet en cas de succès ou lève une exceptionPatternSyntaxException
si une syntaxe d'expression régulière non valide est détectée. Tout objet de la classeMatcher
utilisé parPattern
ou renvoyé par cet objet utilise ses paramètres par défaut, tels que la recherche sensible à la casse. À titre d'exemple, l'extrait de codePattern p = Pattern.compile("(?m)^\\.");
crée un objetPattern
qui stocke une représentation compilée d'une expression régulière pour faire correspondre les chaînes commençant par un point.Pattern compile(String regex, int flags)
résout le même problème quePattern compile(String regex)
, mais en prenant en compteflags
: un ensemble de constantes binaires pour les indicateurs binaires de type OU. La classePattern
déclare des constantesCANON_EQ, CASE_INSENSITIVE, COMMENTS, DOTALL, LITERAL, MULTILINE, UNICODE_CASE, UNICODE_CHARACTER_CLASS и UNIX_LINES
qui peuvent être combinées à l'aide d'un OU au niveau du bit (par exemple,CASE_INSENSITIVE | DOTALL
) et transmises en argumentflags
.
À l'exception de
CANON_EQ, LITERAL и UNICODE_CHARACTER_CLASS
, ces constantes sont une alternative aux expressions d'indicateur imbriquées présentées dans la première partie. Si une constante d'indicateur autre que celles définies dans la classe est rencontrée Pattern
, la méthode Pattern compile(String regex, int flags)
lève une exception java.lang.IllegalArgumentException
. Par exemple, Pattern p = Pattern.compile("^\\.", Pattern.MULTILINE);
équivalent à l'exemple précédent, avec la constante Pattern.MULTILINE
et l'expression d'indicateur imbriquée (?m)
faisant la même chose.
Pattern
, ainsi que les indicateurs qu'elle utilise. Pour ce faire, vous pouvez appeler les méthodes suivantes :
String pattern()
renvoie la chaîne d'expression régulière d'origine compilée dans un fichierPattern
.int flags()
renvoie les drapeaux de l'objetPattern
.
Pattern
, il est généralement utilisé pour obtenir l'objet Matcher
afin d'effectuer des opérations de correspondance de modèles. La méthode Matcher matcher(Charsequence input)
crée un objet Matcher
qui recherche dans le texte input
une correspondance avec un modèle d'objet Pattern
. Lorsqu'il est appelé, il renvoie une référence à cet objet Matcher
. Par exemple, la commande Matcher m = p.matcher(args[1]);
renvoie Matcher
l'objet Pattern
référencé par la variable p
.
Recherche unique |
---|
La méthode static boolean matches(String regex, CharSequence input) de classe Pattern vous permet d'économiser sur la création d'objets Pattern et Matcher la recherche unique à l'aide d'un modèle. Cette méthode renvoie true si input le modèle correspond regex , sinon elle renvoie false. Si l'expression régulière contient une erreur de syntaxe, la méthode lève une exception PatternSyntaxException . Par exemple, System.out.println(Pattern.matches("[a-z[\\s]]*", "all lowercase letters and whitespace only")); imprime true , confirmant que la phrase all lowercase letters and whitespace only ne contient que des espaces et des caractères minuscules. |
Fractionner le texte
La plupart des développeurs ont au moins une fois écrit du code pour diviser le texte saisi en ses composants, comme la conversion d'un compte d'employé basé sur du texte en un ensemble de champs. La classePattern
offre la possibilité de résoudre plus facilement cette tâche fastidieuse en utilisant deux méthodes de fractionnement de texte :
-
La méthode
String[] split(CharSequence text, int limit)
se divisetext
en fonction des correspondances trouvées avec le modèle d'objetPattern
et renvoie les résultats dans un tableau. Chaque élément du tableau spécifie une séquence de texte séparée de la séquence suivante par un fragment de texte correspondant à un motif (ou une fin de texte). Les éléments du tableau sont dans le même ordre dans lequel ils apparaissent danstext
.Dans cette méthode, le nombre d'éléments du tableau dépend du paramètre
limit
, qui contrôle également le nombre de correspondances à trouver.- Une valeur positive ne recherche pas plus de
limit-1
correspondances et la longueur du tableau ne dépasse paslimit
les éléments. - Si la valeur est négative, toutes les correspondances possibles sont recherchées et la longueur du tableau peut être arbitraire.
- Si la valeur est zéro, toutes les correspondances possibles sont recherchées, la longueur du tableau peut être arbitraire et les lignes vides à la fin sont supprimées.
- Une valeur positive ne recherche pas plus de
- La méthode
String[] split(CharSequence text)
appelle la méthode précédente avec 0 comme argument limite et renvoie le résultat de son appel.
split(CharSequence text)
permettant de résoudre le problème de la division d'un compte d'employé en champs distincts de nom, d'âge, d'adresse postale et de salaire :
Pattern p = Pattern.compile(",\\s");
String[] fields = p.split("John Doe, 47, Hillsboro Road, 32000");
for (int i = 0; i < fields.length; i++)
System.out.println(fields[i]);
Le code ci-dessus décrit une expression régulière pour rechercher un caractère virgule immédiatement suivi d'un seul caractère espace. Voici les résultats de son exécution :
John Doe
47
Hillsboro Road
32000
Prédicats de modèle et API Streams
En Java 8,Pattern
une méthode est apparue dans la classe . Cette méthode crée un prédicat (une fonction avec une valeur booléenne) qui est utilisé pour correspondre au modèle. L'utilisation de cette méthode est illustrée dans l'extrait de code suivant : Predicate
asPredicate()
List progLangs = Arrays.asList("apl", "basic", "c", "c++", "c#", "cobol", "java", "javascript", "perl", "python", "scala");
Pattern p = Pattern.compile("^c");
progLangs.stream().filter(p.asPredicate()).forEach(System.out::println);
Ce code crée une liste de noms de langages de programmation, puis compile un modèle pour rechercher tous les noms commençant par la lettre c
. La dernière ligne de code ci-dessus implémente la réception d'un flux de données en série avec cette liste comme source. Il configure un filtre à l'aide d'une fonction booléenne asPredicate()
qui renvoie vrai lorsque le nom commence par une lettre c
et parcourt le flux, imprimant les noms correspondants sur la sortie standard. Cette dernière ligne est équivalente à la boucle régulière suivante, familière de l'application RegexDemo de la partie 1 :
for (String progLang: progLangs)
if (p.matcher(progLang).find())
System.out.println(progLang);
Méthodes de classe Matcher
Une instance de la classeMatcher
décrit un mécanisme permettant d'effectuer des opérations de correspondance de modèles sur une séquence de caractères en interprétant l'expression régulière compilée de la classe Pattern
. Les objets de la classe Matcher
prennent en charge différents types d'opérations de recherche de modèles :
-
La méthode
boolean find()
recherche dans le texte saisi la correspondance suivante. Cette méthode commence l'analyse soit au début du texte spécifié, soit au premier caractère après la correspondance précédente. La deuxième option n'est possible que si l'appel précédent à cette méthode a renvoyé vrai et que le résolveur n'a pas été réinitialisé. Dans tous les cas, si la recherche réussit, la valeur booléenne true est renvoyée. Un exemple de cette méthode peut être trouvé dansRegexDemo
la partie 1. -
La méthode
boolean find(int start)
réinitialise le matcher et recherche dans le texte la correspondance suivante. La visualisation commence à partir de la position spécifiée par le paramètrestart
. Si la recherche réussit, la valeur booléenne true est renvoyée. Par exemple,m.find(1);
analyse le texte à partir de la position1
(la position 0 est ignorée). Si le paramètrestart
contient une valeur négative ou une valeur supérieure à la longueur du texte du correspondant, la méthode lève une exceptionjava.lang.IndexOutOfBoundsException
. -
La méthode
boolean matches()
tente de faire correspondre tout le texte à un modèle. Il renvoie une valeur booléenne vraie si tout le texte correspond au modèle. Par exemple, le codePattern p = Pattern.compile("\\w*"); Matcher m = p.matcher("abc!"); System.out.println(p.matches());
est généréfalse
car le caractère!
n'est pas un caractère de mot. -
La méthode
boolean lookingAt()
essaie de faire correspondre le texte spécifié avec le modèle. Cette méthode renvoie vrai si une partie du texte correspond au modèle. Contrairement à la méthodematches();
, tout le texte ne doit pas nécessairement correspondre au modèle. Par exemple,Pattern p = Pattern.compile("\\w*"); Matcher m = p.matcher("abc!"); System.out.println(p.lookingAt());
il afficheratrue
, puisque le début du texteabc!
se compose uniquement de caractères formant des mots.
Pattern
, les objets de classe Matcher
conservent les informations d'état. Parfois, vous devrez peut-être réinitialiser le matcher pour effacer ces informations une fois la recherche de modèles terminée. Les méthodes suivantes sont disponibles pour réinitialiser le résolveur :
-
La méthode
Matcher reset()
réinitialise l'état du matcher, y compris la position à ajouter à la fin (réinitialisée à 0). L'opération de recherche de modèle suivante commence au début du texte du correspondant. Renvoie une référence à l'objet actuelMatcher
. Par exemple,m.reset();
réinitialise le résolveur référencé parm
. -
La méthode
Matcher reset(CharSequence text)
réinitialise l’état du résolveur et définit le nouveau texte du résolveur surtext
. L'opération de recherche de modèle suivante commence au début du nouveau texte de correspondance. Renvoie une référence à l'objet actuelMatcher
. Par exemple,m.reset("new text");
réinitialise le résolveur référencém
et définit le nouveau texte du résolveur sur"new text"
.
Ajouter du texte à la fin
La position du matcher à ajouter à la fin spécifie le début du texte du matcher qui est ajouté à la fin de l'objet de typejava.lang.StringBuffer
. Les méthodes suivantes utilisent cette position :
-
La méthode
Matcher appendReplacement(StringBuffer sb, String replacement)
lit les caractères du texte du matcher et les ajoute à la fin de l'objetStringBuffer
référencé par l'argumentsb
. Cette méthode arrête la lecture au dernier caractère précédant la correspondance de modèle précédente. Ensuite, la méthode ajoute les caractères de l'objet de typeString
référencé par l'argumentreplacement
à la fin de l'objetStringBuffer
(la chaînereplacement
peut contenir des références à des séquences de texte capturées lors de la recherche précédente ; celles-ci sont spécifiées à l'aide des caractères($)
et des numéros de groupe capturés). Enfin, la méthode définit la valeur de la position du matcher à ajouter à la position du dernier caractère correspondant plus un, puis renvoie une référence au matcher actuel. -
La méthode
StringBuffer appendTail(StringBuffer sb)
ajoute tout le texte à un objetStringBuffer
et renvoie une référence à cet objet. Après le dernier appel de méthodeappendReplacement(StringBuffer sb, String replacement)
, appelez la méthodeappendTail(StringBuffer sb)
pour copier le texte restant dans l'objetStringBuffer
.
La méthode Matcher appendReplacement(StringBuffer sb, String replacement)
lève une exception java.lang.IllegalStateException
si le comparateur n'a pas encore trouvé de correspondance ou si une tentative de recherche précédente a échoué. Il lève une exception IndexOutOfBoundsException
si la ligne replacement
spécifie un groupe de capture qui n'est pas dans le modèle).
Groupes capturés |
---|
Comme vous vous en souvenez de la première partie, un groupe de capture est une séquence de caractères entourés de () métacaractères entre parenthèses ( ). Le but de cette construction est de stocker les caractères trouvés pour une réutilisation ultérieure lors de la correspondance de modèles. Tous les caractères du groupe capturé sont considérés comme un tout lors de la recherche de modèles. |
appendReplacement(StringBuffer sb, String replacement)
et appendTail(StringBuffer sb
pour remplacer toutes les occurrences de la séquence de caractères dans le texte source cat
parcaterpillar
:
Pattern p = Pattern.compile("(cat)");
Matcher m = p.matcher("one cat, two cats, or three cats on a fence");
StringBuffer sb = new StringBuffer();
while (m.find())
m.appendReplacement(sb, "$1erpillar");
m.appendTail(sb);
System.out.println(sb);
L'utilisation d'un groupe capturé et d'une référence à celui-ci dans le texte de remplacement indique au programme d'insérer erpillar
après chaque occurrence de cat
. Le résultat de l'exécution de ce code ressemble à ceci : one caterpillar, two caterpillars, or three caterpillars on a fence
Remplacement du texte
La classeMatcher
nous propose deux méthodes de remplacement de texte, complémentaires au appendReplacement(StringBuffer sb, String replacement)
. En utilisant ces méthodes, vous pouvez remplacer soit la première occurrence du [texte remplacé], soit toutes les occurrences :
-
La méthode
String replaceFirst(String replacement)
réinitialise le matcher, crée un nouvel objetString
, copie tous les caractères du texte du matcher (jusqu'à la première correspondance) dans cette chaîne, ajoute les caractères à la fin de celle-cireplacement
, copie les caractères restants dans la chaîne et renvoie un objetString
(la chaînereplacement
peut contenir des références à celles capturées lors des séquences de texte de recherche précédentes à l'aide de symboles dollar et de numéros de groupe capturés). -
La méthode
String replaceAll(String replacement)
fonctionne de manière similaire à la méthodeString replaceFirst(String replacement)
, mais remplacereplacement
toutes les correspondances trouvées par des caractères de la chaîne.
\s+
recherche un ou plusieurs caractères d'espacement dans le texte saisi. Ci-dessous, nous utiliserons cette expression régulière et appellerons une méthode replaceAll(String replacement)
pour supprimer les espaces en double :
Pattern p = Pattern.compile("\\s+");
Matcher m = p.matcher("Удаляем \t\t лишние пробелы. ");
System.out.println(m.replaceAll(" "));
Voici les résultats : Удаляем лишние пробелы.
Expressions régulières en Java, partie 4 Expressions régulières en Java, partie 5
GO TO FULL VERSION