Regex API を使用して一般的なプログラミング タスクを簡素化する
この記事のパート 1 とパート 2 では、正規表現と Regex API について説明しました。このクラスについて学習しPattern
、リテラル文字列を使用した単純なパターン マッチングから、範囲、境界マッチャー、数量子を使用したより複雑なマッチングまで、正規表現の構成を示す例を学習しました。このパートとその後のパートでは、最初のパートでカバーされていない問題について検討し、クラスおよび のPattern
対応するメソッドを学習します。また、正規表現を使用して一般的なプログラミングの問題を容易にする2 つのユーティリティについても学習します。最初のものは、ドキュメント用にコードからコメントを抽出します。2 つ目は、字句解析を実行するように設計された再利用可能なコードのライブラリです。これは、アセンブラ、コンパイラ、および同様のソフトウェアの重要なコンポーネントです。 Matcher
PatternSyntaxException
ソースコードのダウンロード
この記事のデモ アプリケーションのすべてのソース コード (JavaWorld 用に Jeff Friesen が作成) は、ここから入手できます。Regex API を学ぶ
Pattern
、Matcher
および はPatternSyntaxException
Regex API を構成する 3 つのクラスです。それぞれのメソッドは、コード内で正規表現を使用できるようにするメソッドを提供します。
Pattern クラスのメソッド
クラスのインスタンスはPattern
コンパイルされた正規表現であり、パターンとも呼ばれます。正規表現は、パターン マッチング操作のパフォーマンスを向上させるためにコンパイルされます。次の静的メソッドはコンパイルをサポートしています。
Pattern compile(String regex)
コンテンツをregex
中間表現にコンパイルし、新しい .html ファイルに保存しますPattern
。このメソッドは、成功した場合はオブジェクトへの参照を返し、PatternSyntaxException
無効な正規表現構文が検出された場合は例外をスローします。Matcher
このオブジェクトによって使用される、またはこのオブジェクトから返されるクラスのオブジェクトはPattern
、大文字と小文字を区別した検索などのデフォルト設定を使用します。例として、コード スニペットは、ドット文字で始まる文字列と一致する正規表現のコンパイル済み表現を保存するPattern p = Pattern.compile("(?m)^\\.");
オブジェクトを作成します。Pattern
Pattern compile(String regex, int flags)
は と同じ問題を解決しますが、 OR タイプのビット フラグのビット定数のセットをPattern compile(String regex)
考慮しています。flags
このクラスは、ビットごとの OR (たとえば、) を使用して結合し、引数として渡すことができるPattern
定数を宣言します。CANON_EQ, CASE_INSENSITIVE, COMMENTS, DOTALL, LITERAL, MULTILINE, UNICODE_CASE, UNICODE_CHARACTER_CLASS и UNIX_LINES
CASE_INSENSITIVE | DOTALL
flags
を除き
CANON_EQ, LITERAL и UNICODE_CHARACTER_CLASS
、これらの定数は、パート 1 で説明したネストされたフラグ式の代替です。クラスで定義されているもの以外のフラグ定数が見つかった場合Pattern
、メソッドはPattern compile(String regex, int flags)
例外をスローしますjava.lang.IllegalArgumentException
。たとえば、Pattern p = Pattern.compile("^\\.", Pattern.MULTILINE);
定数Pattern.MULTILINE
とネストされたフラグ式が(?m)
同じことを行う前の例と同等です。
Pattern
と、それが使用するフラグを取得する必要があります。これを行うには、次のメソッドを呼び出すことができます。
String pattern()
にコンパイルされた元の正規表現文字列を返しますPattern
。int flags()
オブジェクトのフラグを返しますPattern
。
Pattern
、通常は、パターン マッチング操作を実行するためにオブジェクトを取得するために使用されますMatcher
。このメソッドは、オブジェクト パターンに一致するテキストを検索するMatcher matcher(Charsequence input)
オブジェクトを作成します。呼び出されると、このオブジェクトへの参照が返されます。たとえば、コマンドは変数によって参照されるオブジェクトに対して戻ります。 Matcher
input
Pattern
Matcher
Matcher m = p.matcher(args[1]);
Matcher
Pattern
p
ワンタイム検索 |
---|
static boolean matches(String regex, CharSequence input) クラスメソッドを使用すると、オブジェクトの作成と、テンプレートを使用した 1 回の検索Pattern を節約できます。このメソッドは、パターンが一致する場合は true を返し、一致しない場合は false を返します。正規表現に構文エラーが含まれている場合、メソッドは例外をスローします。たとえば、を出力して、語句にスペースと小文字のみが含まれていることを確認します。 Pattern Matcher input regex PatternSyntaxException System.out.println(Pattern.matches("[a-z[\\s]]*", "all lowercase letters and whitespace only")); true all lowercase letters and whitespace only |
テキストの分割
ほとんどの開発者は、テキストベースの従業員アカウントを一連のフィールドに変換するなど、入力テキストをコンポーネント部分に分割するコードを少なくとも 1 度は作成したことがあります。このクラスは、Pattern
次の 2 つのテキスト分割メソッドを使用して、この退屈なタスクをより便利に解決する機能を提供します。
-
このメソッドは、見つかったオブジェクト パターンとの一致に従って
String[] split(CharSequence text, int limit)
分割し、結果を配列で返します。各配列要素は、パターン マッチングのテキスト フラグメント (またはテキストの終わり) によって次のシーケンスから区切られたテキスト シーケンスを指定します。配列の要素は、 に出現する順序と同じです。text
Pattern
text
このメソッドでは、配列要素の数はパラメーターによって異なり
limit
、これにより、検索される一致の数も制御されます。- 正の値は一致するもののみを検索し
limit-1
、配列の長さはlimit
要素を超えません。 - 値が負の場合、一致する可能性のあるすべてのものが検索され、配列の長さは任意です。
- 値がゼロの場合、一致する可能性のあるすべてのものが検索され、配列の長さは任意であり、末尾の空行は破棄されます。
- 正の値は一致するもののみを検索し
- このメソッドは、
String[] split(CharSequence text)
limit 引数として 0 を指定して前のメソッドを呼び出し、その呼び出しの結果を返します。
split(CharSequence text)
以下は、従業員アカウントを名前、年齢、住所、給与の個別のフィールドに分割するという問題を解決する 方法の結果です。
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]);
上記のコードは、単一のスペース文字の直後にあるカンマ文字を検索するための正規表現を記述しています。実行結果は次のとおりです。
John Doe
47
Hillsboro Road
32000
テンプレート述部とストリーム API
Java 8 では、クラスにPattern
メソッドが登場しました。このメソッドは、パターンの照合に使用される述語 (ブール値を持つ関数) を作成します。このメソッドの使用方法を次のコード スニペットに示します。 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);
このコードは、プログラミング言語名のリストを作成し、文字 で始まるすべての名前を検索するパターンをコンパイルしますc
。上記のコードの最後の行は、このリストをソースとしてデータのシリアル ストリームの受信を実装します。asPredicate()
名前が文字で始まる場合に true を返すブール関数を使用してフィルターを設定しc
、ストリームを反復処理して、一致する名前を標準出力に出力します。この最後の行は、パート 1 の RegexDemo アプリケーションでおなじみの次の通常のループと同等です。
for (String progLang: progLangs)
if (p.matcher(progLang).find())
System.out.println(progLang);
Matcher クラスのメソッド
クラスのインスタンスは、Matcher
クラスのコンパイルされた正規表現を解釈することによって、一連の文字に対してパターン マッチング操作を実行するメカニズムを記述しますPattern
。このクラスのオブジェクトは、Matcher
さまざまなタイプのパターン検索操作をサポートします。
-
このメソッドは、
boolean find()
入力テキストで次の一致を検索します。このメソッドは、指定されたテキストの先頭、または前の一致後の最初の文字のいずれかでスキャンを開始します。2 番目のオプションは、このメソッドへの前回の呼び出しが true を返し、リゾルバーがリセットされていない場合にのみ可能です。いずれの場合も、検索が成功すると、ブール値 true が返されます。この方法の例はパート 1 にありますRegexDemo
。 -
このメソッドは
boolean find(int start)
マッチャーをリセットし、テキスト内で次の一致を検索します。パラメータで指定した位置から表示を開始しますstart
。検索が成功すると、ブール値 true が返されます。たとえば、m.find(1);
位置から開始してテキストをスキャンします1
(位置 0 は無視されます)。パラメーターにstart
負の値、またはマッチャー テキストの長さを超える値が含まれている場合、メソッドは例外をスローしますjava.lang.IndexOutOfBoundsException
。 -
このメソッドは、
boolean matches()
すべてのテキストをパターンと照合しようとします。すべてのテキストがパターンに一致する場合、ブール値 true を返します。たとえば、文字が単語文字ではないため、コードがPattern p = Pattern.compile("\\w*"); Matcher m = p.matcher("abc!"); System.out.println(p.matches());
出力されます。false
!
-
このメソッドは、
boolean lookingAt()
指定されたテキストとパターンの一致を試みます。このメソッドは、テキストの一部がパターンに一致する場合に true を返します。メソッドとは異なりmatches();
、すべてのテキストがパターンに一致する必要はありません。たとえば、テキストの先頭は単語形成文字のみで構成されているため、Pattern p = Pattern.compile("\\w*"); Matcher m = p.matcher("abc!"); System.out.println(p.lookingAt());
が出力されます。true
abc!
Pattern
、クラス オブジェクトはMatcher
状態情報を保持します。場合によっては、パターン検索の終了後にマッチャーをリセットしてこの情報をクリアする必要がある場合があります。リゾルバをリセットするには、次の方法を使用できます。
-
このメソッドは
Matcher reset()
、末尾に追加される位置を含むマッチャーの状態をリセットします (0 にリセット)。次のパターン検索操作は、マッチャー テキストの先頭から始まります。現在のオブジェクトへの参照を返しますMatcher
。たとえば、m.reset();
によって参照されるリゾルバをリセットしますm
。 -
このメソッドは
Matcher reset(CharSequence text)
リゾルバーの状態をリセットし、新しいリゾルバー テキストを に設定しますtext
。次のパターン検索操作は、新しいマッチャー テキストの先頭から始まります。現在のオブジェクトへの参照を返しますMatcher
。たとえば、m.reset("new text");
参照されたリゾルバをリセットしm
、新しいリゾルバ テキストを に設定します"new text"
。
末尾にテキストを追加する
末尾に追加されるマッチャーの位置は、 type のオブジェクトの末尾に追加されるマッチャー テキストの先頭を指定しますjava.lang.StringBuffer
。次のメソッドはこの位置を使用します。
-
このメソッドは
Matcher appendReplacement(StringBuffer sb, String replacement)
マッチャー テキスト文字を読み取り、StringBuffer
引数で参照されるオブジェクトの末尾に追加しますsb
。このメソッドは、前のパターン一致に先立つ最後の文字で読み取りを停止します。次に、メソッドは、String
引数によって参照される型のオブジェクトの文字をreplacement
オブジェクトの末尾に追加しますStringBuffer
(replacement
文字列には、前の検索中にキャプチャされたテキスト シーケンスへの参照が含まれる場合があります。これらは、キャプチャされる文字($)
とグループ番号を使用して指定されます)。最後に、このメソッドは、最後に一致した文字の位置に 1 を加えた値に追加されるマッチャー位置の値を設定し、現在のマッチャーへの参照を返します。 -
このメソッドは、
StringBuffer appendTail(StringBuffer sb)
すべてのテキストをオブジェクトに追加しStringBuffer
、そのオブジェクトへの参照を返します。最後のメソッド呼び出しの後appendReplacement(StringBuffer sb, String replacement)
、メソッドを呼び出して、appendTail(StringBuffer sb)
残りのテキストをオブジェクトにコピーしますStringBuffer
。
マッチャーが一致をまだ見つけていない場合、または以前の検索試行が失敗した場合、このメソッドはMatcher appendReplacement(StringBuffer sb, String replacement)
例外をスローします。行がパターンにないキャプチャ グループを指定している場合、java.lang.IllegalStateException
例外がスローされます)。IndexOutOfBoundsException
replacement
捕獲されたグループ |
---|
第 1 回で覚えたように、キャプチャ グループは、括弧 ( ) メタキャラクターで囲まれた一連の文字です() 。この構造の目的は、後でパターン マッチング中に再利用できるように、見つかった文字を保存することです。パターン検索中は、キャプチャされたグループのすべての文字が 1 つの全体として考慮されます。 |
appendReplacement(StringBuffer sb, String replacement)
およびメソッドを呼び出してappendTail(StringBuffer sb
、ソース テキスト内のすべての文字シーケンスをcat
に置き換えますcaterpillar
。
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);
erpillar
キャプチャされたグループと置換テキスト内での参照を使用すると、 が出現するたびに プログラムに挿入するように指示されますcat
。このコードを実行した結果は次のようになります。 one caterpillar, two caterpillars, or three caterpillars on a fence
テキストの置換
このクラスは、Matcher
を補完するテキスト置換のための 2 つのメソッドを提供しますappendReplacement(StringBuffer sb, String replacement)
。これらの方法を使用すると、[置換されたテキスト] の最初の出現箇所またはすべての出現箇所を置換できます。
-
このメソッドは
String replaceFirst(String replacement)
マッチャーをリセットし、新しいオブジェクトを作成しString
、マッチャー テキストのすべての文字 (最初の一致まで) をこの文字列にコピーし、 からの文字を文字列の末尾に追加し、残りの文字をreplacement
文字列にコピーして、オブジェクトString
(文字列にreplacement
は、ドル記号とキャプチャされたグループ番号を使用した前の検索テキスト シーケンス中にキャプチャされたオブジェクトへの参照が含まれる場合があります)。 -
このメソッドは
String replaceAll(String replacement)
メソッドと同様に動作しますString replaceFirst(String replacement)
が、replacement
見つかったすべての一致を文字列の文字に置き換えます。
\s+
入力テキスト内の 1 つ以上の空白文字を検索します。replaceAll(String replacement)
以下では、この正規表現を使用して、重複するスペースを削除する メソッドを呼び出します。
Pattern p = Pattern.compile("\\s+");
Matcher m = p.matcher("Удаляем \t\t лишние пробелы. ");
System.out.println(m.replaceAll(" "));
結果は次のとおりです: Удаляем лишние пробелы.
Java の正規表現、パート 4 Java の正規表現、パート 5
GO TO FULL VERSION