Javaでの正規表現へようこそ。Javaでは、正規表現は「Regex」とも呼ばれています。プログラミングを始めた当初、Javaの正規表現は私にとって悪夢でした。このチュートリアルは、Javaでの正規表現をマスターするためのお手伝いをすることを目的としています。私自身もJavaの正規表現学習をリフレッシュするために、ここに戻ってきます。
Javaでの正規表現
Javaでの正規表現は、文字列のパターンを定義します。正規表現は、テキストの検索、編集、または操作に使用することができます。正規表現は言語に依存しないものですが、各言語によって若干異なります。Javaでの正規表現は、Perlに最も似ています。Javaの正規表現クラスは、
java.util.regex
パッケージに存在し、次の3つのクラスが含まれています:
- Pattern:
Pattern
オブジェクトは正規表現のコンパイル済みバージョンです。Patternクラスには公開されたコンストラクタはなく、正規表現の引数を渡してパターンオブジェクトを作成するために、その公開された静的メソッドcompile
を使用します。 - Matcher:
Matcher
は、作成されたパターンオブジェクトと入力文字列パターンをマッチングするJavaの正規表現エンジンオブジェクトです。Matcherクラスには公開コンストラクタがなく、引数として入力文字列を取るパターンオブジェクトmatcher
メソッドを使用してMatcherオブジェクトを取得します。その後、入力文字列が正規表現パターンと一致するかどうかに基づいてブール結果を返すmatches
メソッドを使用します。 - PatternSyntaxException:
PatternSyntaxException
は、正規表現の構文が正しくない場合にスローされます。
Java Regexの例プログラムを見てみましょう。
package com.journaldev.util;
import java.util.regex.*;
public class PatternExample {
public static void main(String[] args) {
Pattern pattern = Pattern.compile(".xx.");
Matcher matcher = pattern.matcher("MxxY");
System.out.println("Input String matches regex - "+matcher.matches());
// 不正な正規表現
pattern = Pattern.compile("*xx*");
}
}
このJava正規表現の例プログラムを実行すると、以下の出力が得られます。
Input String matches regex - true
Exception in thread "main" java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0
*xx*
^
at java.util.regex.Pattern.error(Pattern.java:1924)
at java.util.regex.Pattern.sequence(Pattern.java:2090)
at java.util.regex.Pattern.expr(Pattern.java:1964)
at java.util.regex.Pattern.compile(Pattern.java:1665)
at java.util.regex.Pattern.(Pattern.java:1337)
at java.util.regex.Pattern.compile(Pattern.java:1022)
at com.journaldev.util.PatternExample.main(PatternExample.java:13)
Javaの正規表現は文字列を中心に回転しているため、Java 1.4でStringクラスが拡張され、正規表現パターンマッチングを行うmatches
メソッドが提供されました。内部的には、処理にPattern
およびMatcher
Java正規表現クラスを使用しますが、明らかにコード行数が減少します。Pattern
クラスには、regexと入力文字列を引数として受け取り、それらをマッチングした後にブール結果を返すmatches
メソッドも含まれています。したがって、次のコードは、Javaで正規表現と入力文字列をマッチングするために正常に機能します。
String str = "bbb";
System.out.println("Using String matches method: "+str.matches(".bb"));
System.out.println("Using Pattern matches method: "+Pattern.matches(".bb", str));
もし、あなたの要件が入力された文字列がパターンと一致するかどうかを確認するだけである場合は、単純な文字列の一致メソッドを使用して時間とコードの行数を節約するべきです。PatternとMatchesクラスを使用するのは、入力文字列を操作する必要がある場合やパターンを再利用する必要がある場合のみです。正規表現で定義されたパターンは、左から右に文字列に適用され、一度ソース文字が一致に使用されると再利用することはできません。例えば、正規表現「121」は「31212142121」に対して「_121____121」として2回のみ一致します。
Javaの正規表現 – 一般的な一致記号
Regular Expression | Description | Example |
---|---|---|
. | Matches any single character | (“…”, “a%”) – true(“…”, “.a”) – true (“…”, “a”) – false |
^aaa | Matches aaa regex at the beginning of the line | (“^a.c.”, “abcd”) – true (“^a”, “ac”) – false |
aaa$ | Matches regex aaa at the end of the line | (“…cd$”, “abcd”) – true(“a$”, “a”) – true (“a$”, “aca”) – false |
[abc] | Can match any of the letter a, b or c. [] are known as character classes. | (“^[abc]d.”, “ad9”) – true(“[ab].d$”, “bad”) – true (“[ab]x”, “cx”) – false |
[abc][12] | Can match a, b or c followed by 1 or 2 | (“[ab][12].”, “a2#”) – true(“[ab]…[12]”, “acd2”) – true (“[ab][12]”, “c2”) – false |
[^abc] | When ^ is the first character in [], it negates the pattern, matches anything except a, b or c | (“[^ab][^12].”, “c3#”) – true(“[^ab]…[^12]”, “xcd3”) – true (“[^ab][^12]”, “c2”) – false |
[a-e1-8] | Matches ranges between a to e or 1 to 8 | (“[a-e1-3].”, “d#”) – true(“[a-e1-3]”, “2”) – true (“[a-e1-3]”, “f2”) – false |
xx | yy | Matches regex xx or yy |
Javaの正規表現メタ文字
Javaの正規表現には、一般的な一致パターンのためのショートコードのようなメタ文字があります。
Regular Expression | Description |
---|---|
\d | Any digits, short of [0-9] |
\D | Any non-digit, short for [^0-9] |
\s | Any whitespace character, short for [\t\n\x0B\f\r] |
\S | Any non-whitespace character, short for [^\s] |
\w | Any word character, short for [a-zA-Z_0-9] |
\W | Any non-word character, short for [^\w] |
\b | A word boundary |
\B | A non word boundary |
正規表現内のメタ文字を通常の文字として使用する方法は2つあります。
- メタ文字の前にバックスラッシュ(\)を付ける。
- メタ文字を\Q(引用の開始)と\E(引用の終了)で囲んで保持する。
Javaでの正規表現 – 量指定子
Javaの正規表現量指定子は、一致させる文字の出現回数を指定します。
Regular Expression | Description |
---|---|
x? | x occurs once or not at all |
X* | X occurs zero or more times |
X+ | X occurs one or more times |
X{n} | X occurs exactly n times |
X{n,} | X occurs n or more times |
X{n,m} | X occurs at least n times but not more than m times |
Javaの正規表現量指定子は、文字クラスやキャプチャリンググループとも使用できます。例えば、[abc]+は、a、b、またはcのいずれかが1回以上繰り返されることを意味します。また、(abc)+はグループ “abc” が1回以上繰り返されることを意味します。今はキャプチャリンググループについて議論します。
Javaでの正規表現 – キャプチャリンググループ
Javaでの正規表現キャプチャリンググループは、複数の文字を単一の単位として扱うために使用されます。()
を使用してグループを作成できます。キャプチャリンググループに一致する入力文字列の部分はメモリに保存され、後方参照を使用して再呼び出しができます。javaの正規表現パターンにおけるキャプチャリンググループの数を知るためにmatcher.groupCount
メソッドを使用できます。例えば、((a)(bc))には3つのキャプチャリンググループが含まれます – ((a)(bc))、(a)、および(bc)。後方参照はバックスラッシュ(\)とグループ番号を続けて使用できます。キャプチャリンググループと後方参照は混乱することがあるので、例を用いて理解しましょう。
System.out.println(Pattern.matches("(\\w\\d)\\1", "a2a2")); //true
System.out.println(Pattern.matches("(\\w\\d)\\1", "a2b2")); //false
System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B2AB")); //true
System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B3AB")); //false
最初の例では、実行時に最初のキャプチャグループが(\w\d)であり、入力文字列”a2a2″と一致した場合、”a2″としてメモリに保存されます。したがって、\1は”a2″を参照しており、それによりtrueが返されます。同じ理由で、2番目の文はfalseを出力します。文3と4のシナリオを理解しようとしてください。 🙂 今度はPatternクラスとMatcherクラスのいくつかの重要なメソッドを見てみましょう。
- フラグを使用してPatternオブジェクトを作成できます。例えば、
Pattern.CASE_INSENSITIVE
は大文字と小文字を区別しない一致を可能にします。 - Patternクラスはまた、Stringクラスの
split()
メソッドと似たsplit(String)
メソッドを提供します。 - Patternクラスの
toString()
メソッドは、このパターンがコンパイルされた正規表現文字列を返します。 - Matcherクラスには、一致が入力文字列で見つかった場所を正確に示す
start()
およびend()
インデックスメソッドがあります。 - Matcherクラスはまた、文字列操作メソッド
replaceAll(String replacement)
とreplaceFirst(String replacement)
を提供します。
これらのJava正規表現メソッドを単純な例プログラムで見てみましょう。
package com.journaldev.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexExamples {
public static void main(String[] args) {
// フラグを使用したパターンの使用
Pattern pattern = Pattern.compile("ab", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher("ABcabdAb");
// Matcherのfind()、group()、start()、end()メソッドの使用
while (matcher.find()) {
System.out.println("Found the text \"" + matcher.group()
+ "\" starting at " + matcher.start()
+ " index and ending at index " + matcher.end());
}
// Patternのsplit()メソッドの使用
pattern = Pattern.compile("\\W");
String[] words = pattern.split("one@two#three:four$five");
for (String s : words) {
System.out.println("Split using Pattern.split(): " + s);
}
// Matcher.replaceFirst()およびreplaceAll()メソッドの使用
pattern = Pattern.compile("1*2");
matcher = pattern.matcher("11234512678");
System.out.println("Using replaceAll: " + matcher.replaceAll("_"));
System.out.println("Using replaceFirst: " + matcher.replaceFirst("_"));
}
}
上記のJava正規表現例プログラムの出力は次のとおりです。
Found the text "AB" starting at 0 index and ending at index 2
Found the text "ab" starting at 3 index and ending at index 5
Found the text "Ab" starting at 6 index and ending at index 8
Split using Pattern.split(): one
Split using Pattern.split(): two
Split using Pattern.split(): three
Split using Pattern.split(): four
Split using Pattern.split(): five
Using replaceAll: _345_678
Using replaceFirst: _34512678
それで、Javaの正規表現に関するすべてです。Javaの正規表現は最初は難しく見えますが、しばらく使ってみると、学びやすく使いやすくなります。
完全なコードやさらなる正規表現の例は、当社のGitHubリポジトリからご確認いただけます。
Source:
https://www.digitalocean.com/community/tutorials/regular-expression-in-java-regex-example