Diverses notes sur l'utilisation des expressions régulières en Java.
Il existe plusieurs méthodes dans String
qui acceptent les expressions régulières.
matches(String)
package sample.regexp;
public class Main {
public static void main(String[] args) {
String text = "abc123";
System.out.println(text.matches("[a-z0-9]+"));
System.out.println(text.matches("[a-z]+"));
}
}
Résultat d'exécution
true
false
--Vérifiez que la chaîne correspond ** exactement ** à l'expression régulière spécifiée
--Si seulement une partie correspond, ce sera faux
replaceAll(String, String)
package sample.regexp;
public class Main {
public static void main(String[] args) {
String text = "abc123";
System.out.println(text.replaceAll("[a-z]", "*"));
}
}
Résultat d'exécution
***123
--Passez une expression régulière comme premier argument et remplacez toutes les parties correspondantes par la chaîne de caractères du deuxième argument
package sample.regexp;
public class Main {
public static void main(String[] args) {
String text = "<<abc123>>";
System.out.println(text.replaceAll("([a-z]+)([0-9]+)", "$0, $1, $2"));
}
}
Résultat d'exécution
<<abc123, abc, 123>>
$ n
dans la chaîne de remplacement, le groupe correspondant peut être réutilisé après remplacement.
-- n
commence par 0
--0
fait référence à toute la chaîne correspondante([a-z] +) ([0-9] +)
, ʻabc123` est la cible. $ 1
correspond à([a-z] +)
, mais ʻabc est --
$ 2 est pour
123qui correspond à
([0-9] +)--Si vous spécifiez
n avec un nombre supérieur au nombre de groupes correspondants, ʻIndexOutOfBoundsException
est levée.
--Si vous voulez simplement le remplacer par la chaîne $
, échappez-le avec une barre oblique inverse (\
)
text.replaceAll("[a-z]+", "\\$")
--S'il n'est pas échappé, ʻIllegalArgumentException` est levéreplaceFirst(String, String)
package sample.regexp;
public class Main {
public static void main(String[] args) {
String text = "abc123";
System.out.println(text.replaceFirst("[a-z]", "*"));
}
}
Résultat d'exécution
*bc123
--Remplacez uniquement la première partie correspondante de la sous-chaîne qui correspond à l'expression régulière
--La sous-chaîne peut être référencée avec $ n
, qui est identique à replaceAll ()
.
split(String, int)
package sample.regexp;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
String text = "a1b2";
for (int i=-1; i<5; i++) {
String[] elements = text.split("[0-9]", i);
System.out.println("limit=" + i + ",\telements=" + Arrays.toString(elements));
}
}
}
Résultat d'exécution
limit=-1, elements=[a, b, ]
limit=0, elements=[a, b]
limit=1, elements=[a1b2]
limit=2, elements=[a, b2]
limit=3, elements=[a, b, ]
limit=4, elements=[a, b, ]
--Split la chaîne à l'emplacement qui correspond à l'expression régulière spécifiée dans le premier argument
limit
, détermine la limite supérieure de la taille du tableau de retour.limit == 1
, alors limit -1 => 0
, donc aucun fractionnement n'est effectué (en conséquence, la taille du tableau est" 1 ").limit == 2
, il devient limit --1 => 1
, donc la division est effectuée à la partie" 1 de ʻa1b2
qui correspond en premier à l'expression régulière` [0-9] ". Nous terminons ensuite le fractionnement (résultant en une taille de tableau de «2»)Si le début devient vide suite à la division, le blanc est défini comme un élément du tableau tel quel.
package sample.regexp;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
String text = "0a1b2";
String[] elements = text.split("[0-9]", 0);
System.out.println(Arrays.toString(elements));
}
}
Résultat d'exécution
[, a, b]
split(String)
C'est le même comportement que de définir le deuxième argument de split (String, int)
sur 0
.
À quelques exceptions près [^ 1], méthodes qui utilisent la délégation canonique de la classe String
à la classe Pattern
dans les coulisses.
Par exemple, si vous vérifiez l'implémentation de la méthode replaceAll ()
, cela ressemble à ceci:
String.replaceAll()
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
Cette classe Pattern
(et Matcher
) est en charge du traitement des expressions régulières en Java.
La classe «Pattern» interprète la chaîne passée par «compile ()» comme une expression régulière.
Si l'expression régulière utilisée est fixe, il est plus efficace d'exécuter cette compile ()
seulement la première fois, puis de réutiliser l'instance Pattern
.
(La classe Pattern
est immuable, elle peut donc être réutilisée en toute sécurité même en multithreading.)
Cependant, ce compile ()
est exécuté à chaque fois lors de l'utilisation de la méthode qui utilise l'expression régulière de la classe String
.
Par conséquent, si vous utilisez la méthode String
lorsque vous souhaitez exécuter une expression régulière fixe encore et encore, la vitesse de traitement sera plus lente que l'utilisation de l'instance Pattern
.
Exemple d'utilisation de Pattern
public class Hoge {
//Réutiliser l'instance de Pattern compilée
private static final Pattern HOGE_PATTERN = Pattern.compile("[0-9]+");
public boolean test(String text) {
return HOGE_PATTERN.matcher(text).matches(); //Le mouvement est texte.maches("[0-9]+")Pareil que
}
}
package sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
Pattern pattern = Pattern.compile("[0-9]+");
Matcher abc = pattern.matcher("123abc");
System.out.println(abc.matches());
Matcher _123 = pattern.matcher("123");
System.out.println(_123.matches());
}
}
Résultat d'exécution
false
true
Pattern.compile (String)
et obtenez l'instance Pattern
.Pattern.matcher (String)
et obtenez l'instance Matcher
.
--Utilisez l'instance Matcher
acquise pour vérifier si elle correspond ou non.
--Matcher.matches ()
vérifie que toute la séquence d'entrée correspond à l'expression régulière et renvoie un résultat avec booléen
package sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.Arrays;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
Pattern pattern = Pattern.compile("[a-z]+");
String[] elements = pattern.split("123abc456def789ghi");
System.out.println(Arrays.toString(elements));
elements = pattern.split("123abc456def789ghi", -1);
System.out.println(Arrays.toString(elements));
}
}
Résultat d'exécution
[123, 456, 789]
[123, 456, 789, ]
--Avec Pattern.split (String)
, divisez la chaîne au niveau de la partie de la chaîne spécifiée qui correspond à l'expression régulière.
String.split (String)
, String.split (String, int)
Matcher
--Pattern
est une classe qui interprète les expressions régulières et Matcher
effectue le traitement suivant.
Matcher
est utilisé dans les étapes suivantes.start ()
Début de l'index sur la séquence d'entrée correspondante
--ʻEnd () ʻEnd index sur la séquence d'entrée correspondante + 1
--group ()
Sous-chaîne correspondante
--Si vous exécutez ces méthodes sans effectuer d'opération de correspondance, ʻIllegalStateException` sera levé.Matcher
n'est pas thread-safe **Il y a trois opérations de match dans Matcher
.
matches()
--Vérifiez que la séquence d'entrée entière correspond à l'expression régulièrelookingAt()
--Vérifiez si l'expression régulière correspond au début de la séquence d'entréefind()
--Vérifiez dans l'ordre s'il y a une partie qui correspond à l'expression régulière dans la séquence d'entréematches()
package sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
test("abc");
test("abc123");
}
private static void test(String text) {
Pattern pattern = Pattern.compile("[a-z]+");
Matcher matcher = pattern.matcher(text);
System.out.println("[text=" + text + "]");
if (matcher.matches()) {
System.out.println("matches = true");
System.out.println("start = " + matcher.start());
System.out.println("end = " + matcher.end());
System.out.println("group = " + matcher.group());
} else {
System.out.println("matches = false");
}
}
}
Résultat d'exécution
[text=abc]
matches = true
start = 0
end = 3
group = abc
[text=abc123]
matches = false
--matches ()
vérifie que toute la séquence d'entrée correspond à l'expression régulière
--Retourne true
si la correspondance est établie
lookingAt()
package sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
test("abc");
test("123abc");
test("ab12");
}
private static void test(String text) {
Pattern pattern = Pattern.compile("[a-z]+");
Matcher matcher = pattern.matcher(text);
System.out.println("[text=" + text + "]");
if (matcher.lookingAt()) {
System.out.println("lookingAt = true");
System.out.println("start = " + matcher.start());
System.out.println("end = " + matcher.end());
System.out.println("group = " + matcher.group());
} else {
System.out.println("lookingAt = false");
}
}
}
Résultat d'exécution
[text=abc]
lookingAt = true
start = 0
end = 3
group = abc
[text=123abc]
lookingAt = false
[text=ab12]
lookingAt = true
start = 0
end = 2
group = ab
--lookingAt ()
vérifie que l'expression régulière correspond au début de la séquence d'entrée
--Si la vérification résulte du début de la correspondance, true
est renvoyé (le tout ne doit pas nécessairement correspondre)
find()
package sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
test("abc");
test("123abc456def789");
}
private static void test(String text) {
Pattern pattern = Pattern.compile("[a-z]+");
Matcher matcher = pattern.matcher(text);
System.out.println("[text=" + text + "]");
while (matcher.find()) {
System.out.println("start = " + matcher.start());
System.out.println("end = " + matcher.end());
System.out.println("group = " + matcher.group());
}
}
}
Résultat d'exécution
[text=abc]
start = 0
end = 3
group = abc
[text=123abc456def789]
start = 3
end = 6
group = abc
start = 9
end = 12
group = def
find ()
scanne le début de la séquence d'entrée pour une correspondance avec l'expression régulière.
--Retourne true
s'il y a une sous-chaîne correspondantefind ()
, il recherchera une sous-chaîne qui correspond à nouveau à la partie précédemment mise en correspondance.start ()
, ʻend (),
group ()` renvoie le résultat de la dernière correspondancepackage sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
Pattern pattern = Pattern.compile("[a-z]+");
Matcher matcher = pattern.matcher("abc123def");
System.out.println("replaceAll = " + matcher.replaceAll("*"));
System.out.println("replaceFirst = " + matcher.replaceFirst("*"));
}
}
Résultat d'exécution
replaceAll = *123*
replaceFirst = *123def
--Remplacez toutes les sous-chaînes correspondantes par Matcher.replaceAll (String)
--Matcher.replaceFirst (String)
remplace uniquement la première sous-chaîne correspondante
package sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
Pattern pattern = Pattern.compile("([a-z]+)([0-9]+)");
Matcher matcher = pattern.matcher("abc123de45fg");
int groupCount = matcher.groupCount();
System.out.println("groupCount=" + groupCount);
while (matcher.find()) {
System.out.println("==========");
String group = matcher.group();
System.out.println("group=" + group);
for (int i=0; i<=groupCount; i++) {
String g = matcher.group(i);
System.out.println("group(" + i + ")=" + g);
}
}
}
}
Résultat d'exécution
groupCount=2
==========
group=abc123
group(0)=abc123
group(1)=abc
group(2)=123
==========
group=de45
group(0)=de45
group(1)=de
group(2)=45
()
).
--groupCount ()
Récupère le nombre de groupes définis par l'expression régulière
--group ()
Récupère la chaîne entière correspondant à l'opération de correspondance la plus récente
--group (int)
Récupère le groupe de l'index spécifié parmi les groupes mis en correspondance dans la dernière opération de correspondance.
--Le nombre «0» est la chaîne entière correspondante, il renvoie donc le même résultat que «group ()package sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
Pattern pattern = Pattern.compile("(?<alphabets>[a-z]+)(?<numbers>[0-9]+)");
Matcher matcher = pattern.matcher("abc123de45fg");
while (matcher.find()) {
System.out.println("==========");
System.out.println("group(alphabets)=" + matcher.group("alphabets"));
System.out.println("group(numbers)=" + matcher.group("numbers"));
}
}
}
Résultat d'exécution
==========
group(alphabets)=abc
group(numbers)=123
==========
group(alphabets)=de
group(numbers)=45
(? <Nom du groupe> modèle)
.group (String)
.Pour faire référence au nom du groupe dans la chaîne de remplacement, procédez comme suit:
package sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
Pattern pattern = Pattern.compile("(?<alphabets>[a-z]+)(?<numbers>[0-9]+)");
Matcher matcher = pattern.matcher("abc123def456");
String replaced = matcher.replaceAll("${numbers}${alphabets}");
System.out.println(replaced);
}
}
Résultat d'exécution
123abc456def
$ {nom du groupe}
--Lors de la création d'une instance Pattern
, vous pouvez ajuster la façon dont l'expression régulière est interprétée avec le ** flag **.
Compiler avec des indicateurs
Pattern pattern = Pattern.compile("[a-z]", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
compile (String, int)
|
.package sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
Pattern pattern = Pattern.compile("[a-z]+", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher("ABC");
System.out.println(matcher.matches());
}
}
Résultat d'exécution
true
--Si vous spécifiez CASE_INSENSITIVE
, la correspondance est insensible à la casse.
package sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
Pattern pattern = Pattern.compile("[a-zA-Z]+", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
Matcher matcher = pattern.matcher("ABCabc");
System.out.println(matcher.matches());
}
}
Résultat d'exécution
true
et de
CASE_INSENSITIVE` fournit une correspondance insensible à la casse en Unicodepackage sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
Pattern pattern = Pattern.compile("[a-z]+", Pattern.LITERAL);
Matcher matcher = pattern.matcher("abc");
System.out.println(matcher.matches());
matcher = pattern.matcher("[a-z]+");
System.out.println(matcher.matches());
}
}
Résultat d'exécution
false
true
--Si LITERAL
est spécifié, la chaîne de caractères passée dans le premier argument de` compile (String, int) ʻest traitée comme une simple chaîne de caractères.
package sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
test("[default]", () -> Pattern.compile("^[a-z]+$"));
test("[MULTILINE]", () -> Pattern.compile("^[a-z]+$", Pattern.MULTILINE));
}
private static void test(String label, Supplier<Pattern> patternSupplier) {
System.out.println(label);
Pattern pattern = patternSupplier.get();
String text = "abc\n"
+ "def\n";
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
String group = matcher.group();
System.out.println(group);
}
}
}
Résultat d'exécution
[default]
[MULTILINE]
abc
def
--Lorsque MULTILINE
est spécifié, la gestion de ^ ʻet
MULTILINE
est spécifié, chacun séparé par un saut de ligne est traité comme une chaîne de caractères, donc ^ ʻet
$` correspondront au début et à la fin de chaque ligne.
package sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
String regexp = "#Cette ligne est ignorée en tant que commentaire\n"
+ " [a-z]+ ";
Pattern pattern = Pattern.compile(regexp, Pattern.COMMENTS);
Matcher matcher = pattern.matcher("abc");
System.out.println(matcher.matches());
}
}
Résultat d'exécution
true
--Si «COMMENTAIRES» est spécifié, les chaînes de caractères suivantes seront traitées comme des commentaires et ignorées.
--De #
à la fin de la ligne
--Espace vide
.
)package sample.regexp;
import org.openjdk.jmh.runner.RunnerException;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws RunnerException {
test("[default1]", () -> Pattern.compile(".+"));
test("[default2]", () -> Pattern.compile(".+$"));
test("[DOTALL]", () -> Pattern.compile(".+", Pattern.DOTALL));
}
private static void test(String label, Supplier<Pattern> patternSupplier) {
System.out.println(label);
Pattern pattern = patternSupplier.get();
String text = "abc\n"
+ "def\n";
Matcher matcher = pattern.matcher(text);
if (matcher.find()) {
String group = matcher.group();
System.out.println(group);
}
}
}
Résultat d'exécution
[default1]
abc
[default2]
def
[DOTALL]
abc
def
--Si DOTALL
est spécifié, .
correspondra également à la fin de la ligne.
--Par défaut, .
ne correspond pas à la fin de la ligne
[^ 1]: Par exemple, la méthode split (String regexp)
effectue un traitement fractionné sans utiliser Pattern
lorsque regexp
est une chaîne de caractères simples qui n'utilise pas les méta-caractères des expressions régulières. En train d'aller
Recommended Posts