Jeff Friesen がjavaworld Web サイト 用に書いた、Java の正規表現に関する短いガイドの翻訳を紹介します。読みやすくするために、記事をいくつかの部分に分割しました。
Java の正規表現、パート 1
複数の範囲を結合する |
複数の範囲を並べて配置することで、複数の範囲を 1 つの範囲文字クラスにマージできます。たとえば、このクラスは、[a-zA-Z] 小文字または大文字のすべてのラテン文字に一致します。 |
複数の範囲を結合する
複数の範囲を並べて配置することで、複数の範囲を 1 つの範囲文字クラスにマージできます。たとえば、このクラスは、
[a-zA-Z]
小文字または大文字のすべてのラテン文字に一致します。
文字クラスの結合
文字クラス共用体は、複数のネストされた文字クラスで構成され、結果の共用体のすべての文字と一致します。たとえば、クラスはtoと from to
[a-d[m-p]]
の文字に一致します。次の例を考えてみましょう。 この例では、に一致する 文字、、、およびが検索されます。
a
d
m
p
java RegexDemo [ab[c-e]] abcdef
a
b
c
d
e
abcdef
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
文字クラスの交差
文字クラスの共通部分は、すべてのネストされたクラスに共通の文字で構成され、共通の文字のみに一致します。たとえば、クラスは
[a-z&&[d-f]]
文字
d
、
e
およびに一致します
f
。次の例を考えてみましょう。
java RegexDemo "[aeiouy&&[y]]" party
Windows オペレーティング システムでは、コマンド シェルが二重引用符を
&
コマンド区切り文字として扱うため、二重引用符が必要であることに注意してください。
y
この例では、以下に一致する文字のみを検索します
party
。
regex = [aeiouy&&[y]]
input = party
Found [y] starting at 4 and ending at 4
文字クラスの減算
文字クラスの減算は、ネストされた文字クラスに含まれる文字を除くすべての文字で構成され、残りの文字のみと一致します。たとえば、クラスはtoと from to
[a-z&&[^m-p]]
の文字に一致します。 この例では、 に一致する 文字と が検索されます。
a
l
q
z
java RegexDemo "[a-f&&[^a-c]&&[^e]]" abcdefg
d
f
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
事前定義された文字クラス
一部の文字クラスは、省略表記の使用を正当化するために
正規表現に頻繁に出現します。このクラスは、
Pattern
そのような略語として事前定義された文字クラスを提供します。これらを使用すると、正規表現を簡素化し、構文エラーを最小限に抑えることができます。事前定義された文字クラスには、
java.lang.Character
スクリプト、ブロック、カテゴリ、バイナリなどの標準、POSIX、および Unicode プロパティなどのいくつかのカテゴリがあります。次のリストは、標準クラスのカテゴリのみを示しています。
\d
: 番号。同等[0-9]
。
\D
: 数字以外の文字。同等[^0-9]
。
\s
: 空白文字。同等[ \t\n\x0B\f\r]
。
\S
: 空白文字ではありません。同等[^\s]
。
\w
: 単語を構成する記号。同等[a-zA-Z_0-9]
。
\W
: 語を構成する文字ではありません。同等[^\w]
。
次の例では、事前定義された文字クラスを使用して、
\w
入力テキスト内のすべての単語文字を記述します。
java RegexDemo \w "aZ.8 _"
次の実行結果をよく見てください。ピリオドとスペース文字が単語文字とみなされないことがわかります。
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
行区切り文字 |
クラス SDK のドキュメントでは、Pattern ドット メタキャラクタは、行区切り文字 (行の終わりを示す 1 文字または 2 文字のシーケンス) を除く任意の文字に一致する事前定義された文字クラスとして説明されています。例外は dotall モード (次に説明します) で、このモードではドットも行区切り文字と一致します。このクラスは、Pattern 次の行区切り文字を区別します。
- 復帰文字 (
\r );
- 改行文字 (用紙を 1 行進めるための記号) (
\n );
- 復帰文字の直後に改行文字 (
\r\n ) が続きます。
- 次の行の文字 (
\u0085 );
- 行区切り文字 (
\u2028 );
- 段落区切り記号 (
\u2029 )
|
捕獲されたグループ
キャプチャ グループは、パターンによる検索時にさらに使用できるように、見つかった文字のセットを保存するために使用されます。この構造は、メタキャラクターで括弧 ( ) で囲まれた一連の文字です
( )
。パターンによる検索では、キャプチャされたグループ内のすべての文字が 1 つの全体として考慮されます。たとえば、キャプチャ グループ (
Java
) は、文字
J
、
a
、
v
および を
a
1 つの単位に結合します。
Java
このキャプチャ グループは、入力テキスト内のパターンの出現をすべて検索します。一致するたびに、以前に保存されていた文字が
Java
次の文字に置き換えられます。キャプチャされたグループは、他のキャプチャされたグループ内にネストできます。たとえば、正規表現では、
(Java( language))
グループは
(language)
グループ内にネストされます
(Java)
。ネストされたキャプチャ グループまたはネストされていない各キャプチャ グループには、1 から始まる番号が割り当てられ、番号は左から右の順に付けられます。前の例では、
(Java( language))
はキャプチャ グループ番号 1 と一致し、
(language)
キャプチャ グループ番号 2 と一致します。正規表現 では
(a)(b)
、
(a)
はキャプチャ グループ番号 1 と
(b)
キャプチャ グループ番号 2 に一致
します。キャプチャ グループによって保存された一致には、後方参照を使用して後でアクセスできます。バックスラッシュ文字とその後にキャプチャされるグループの番号に対応する数値を指定すると、後方参照を使用して、グループによってキャプチャされたテキスト内の文字を参照できるようになります。バックリンクがあると、マッチャーはその番号に基づいてキャプチャされたグループの保存された検索結果を参照し、その結果の文字を使用してさらなる検索を試みます。次の例は、後方参照を使用してテキスト内の文法エラーを検索する方法を示しています。
java RegexDemo "(Java( language)\2)" "The Java language language"
この例では、
(Java( language)\2)
正規表現を使用して、入力テキストの
language
直後に重複する単語がある文法エラーを検索します。この正規表現は、キャプチャする 2 つのグループを指定します。番号 1 –は に対応し、番号 2 –はその後のスペース文字に対応します。後方参照を使用すると、グループ番号 2 の保存された結果を再参照できるため、マッチャーは、最初にスペースと が出現した直後に、その後に が続くスペースの 2 番目の出現を検索できます。マッチャーの結果は次のとおりです。
Java
"The Java language language"
(Java( language)\2)
Java language language
(language)
language
\2
language
language
RegexDemo
regex = (Java( language)\2)
input = The Java language language
Found [Java language language] starting at 4 and ending at 25
境界マッチャー
場合によっては、行の先頭、単語の境界、テキストの末尾などでパターン マッチを実行する必要があります。これを行うには、クラス エッジ マッチャー のいずれかを使用します
Pattern
。これは、次の場所で一致するものを検索する正規表現構造です。
^
: 行の先頭。
$
: 行末;
\b
: 単語の境界。
\B
: 擬似ワード境界。
\A
: テキストの先頭。
\G
: 前の試合の終了。
\Z
: テキストの終わり。最後の行区切り文字 (存在する場合) はカウントされません。
\z
:本文終わり
次の例では、
^
境界マッチャー メタキャラクタを使用して、 で始まり
The
、その後に 0 個以上の単語文字が続く行を検索します。
java RegexDemo "^The\w*" Therefore
この文字は、入力テキストの最初の 3 文字が連続するパターン文字および と
^
一致する必要があることを指定します
T
。その後に任意の数字を続けることができます。単語を構成する記号のこと。実行結果は次のとおりです。
h
e
regex = ^The\w*
input = Therefore
Found [Therefore] starting at 0 and ending at 8
コマンドラインを次のように変更するとどうなりますか
java RegexDemo "^The\w*" " Therefore"
?
Therefore
入力テキストの前にスペース文字がある ため、一致するものは見つかりません。
長さゼロの一致
エッジ マッチャーを使用する場合、長さがゼロの一致が発生することがあります。
Совпадение нулевой длины
は文字を含まない一致です。これらは、空の入力テキスト、入力テキストの先頭、入力テキストの最後の文字の後、および入力テキストの任意の 2 文字の間に発生する可能性があります。長さゼロの一致は常に同じ位置で開始および終了するため、簡単に認識できます。次の例を考えてみましょう。
java RegExDemo \b\b "Java is"
この例では、2 つの連続する単語の境界を検索し、結果は次のようになります。
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
結果には長さゼロの一致がいくつか見られます。
RegexDemo
リスト 1 のソース コードで指定したため、ここでの終了位置は開始位置より 1 つ減ります
end() – 1
。
数量指定子
量指定子は、パターンを明示的または暗黙的に数値に関連付ける正規表現の構成要素です。この数値により、パターンを検索する回数が決まります。量指定子は、貪欲、怠惰、超貪欲に分類されます。
- 欲張り数量指定子 (
?
、*
または+
) は、最長一致を検索するように設計されています。質問してもいいですかX
?1 つまたはそれ以下の出現を検索する、X
0個以上の出現を検索する、1 つまたは複数の出現を検索する、出現を検索する、少なくとも (場合によってはそれ以上) の出現を検索する、および少なくとも(それ以上ではない)出現を検索する。X*
X
X+
X
X{n}
n
X
X{n,}
n
X
X{n,m}
n
m
X
- 遅延量指定子 (
??
、*?
または+?
) は、最短の一致を見つけるように設計されています。X??
1 つ以下のX
, X*
?の出現を検索するように指定できます。0 件以上の出現を検索するX
、X+?
1 つ以上の出現を検索するX
、出現をX{n}?
検索する、少なくとも (場合によってはそれ以上) の出現を検索する、および少なくとも (ただしそれ以上の)出現を検索する。n
X
X{n,}?
n
X
X{n,m}?
n
m
X
- 超貪欲量指定子 (
?+
、*+
または++
) は貪欲量指定子と似ていますが、超貪欲量指定子は最長一致の検索を 1 回のみ試行するのに対し、貪欲量指定子は複数回試行できる点が異なります。X?+
1 つまたはそれ以下の出現を検索するX
、 0 つX*+
以上の出現を検索するX
、X++
1 つまたは複数の出現を検索する、X
の出現をX{n}+
検索する、少なくとも (場合によってはそれ以上) の出現を検索する、および少なくとも1 つ以上の出現を検索するように設定できます。。n
X
X{n,}+
n
X
X{n,m}+
n
m
X
次の例は、貪欲量指定子の使用を示しています。
java RegexDemo .*ox "fox box pox"
結果は次のとおりです。
regex = .*ox
input = fox box pox
Found [fox box pox] starting at 0 and ending at 10
貪欲量指定子 (
.*
) は、 で終わる最長の文字シーケンスを検索します
ox
。入力テキスト全体が消費され、入力テキストがこれらの文字で終わっていることが検出されるまでロールバックされます。ここで遅延量指定子を考えてみましょう。
java RegexDemo .*?ox "fox box pox"
その結果は次のとおりです。
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
遅延量指定子 (
.*?
) は、 で終わる文字の最短シーケンスを検索します
ox
。空白の文字列から始まり、一致する文字列が見つかるまで徐々に文字を消費していきます。そして、入力テキストがなくなるまで作業を続けます。最後に、非常に貪欲な量指定子を見てみましょう:
java RegexDemo .*+ox "fox box pox"
そして、その結果は次のとおりです。
regex = .*+ox
input = fox box pox
非常に貪欲な量指定子 ( ) は、すべての入力テキストを消費し、正規表現の最後には
.*+
一致するものが何も残っていないため、一致を見つけられません。
ox
貪欲量指定子とは異なり、超貪欲量指定子はロールバックしません。
長さゼロの一致
量指定子を使用する場合、長さがゼロの一致が発生することがあります。たとえば、次の貪欲量指定子を使用すると、長さゼロの一致が複数発生します。
java RegexDemo a? abaa
この例の実行結果:
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
実行結果には 5 件の一致があります。
a
1 つ目、3 つ目、4 つ目はかなり予想通りですが (の3 文字の位置に対応します
abaa
)、2 つ目と 5 つ目は驚くかもしれません。
a
文章の終わりに相当するものを示しているように見えます
b
が、実際はそうではありません。正規表現ではテキストの末尾は
a?
検索されません。
b
有無を検索します
a
。
a?
が見つからない場合は
a
、長さがゼロの一致として報告されます。
ネストされたフラグ式
マッチャーは、正規表現をパターンにコンパイルするときにオーバーライドできるいくつかのデフォルトの仮定を作成します。この問題については後で説明します。正規表現を使用すると、ネストされたフラグ式を使用してデフォルトをオーバーライドできます。この正規表現構造は、疑問符メタキャラクタ (
?
) を囲むかっこのメタキャラクタとして指定され、その後に小文字のラテン文字が続きます。このクラスは、
Pattern
次のネストされたフラグ式を理解します。
(?i)
: 大文字と小文字を区別しないパターン マッチングを有効にします。たとえば、コマンドを使用する場合、java RegexDemo (?i)tree Treehouse
文字のシーケンスはTree
パターンと一致しますtree
。デフォルトでは、大文字と小文字を区別したパターン検索が行われます。
(?x)
: パターン内でメタキャラクターで始まる空白文字とコメントの使用を許可します#
。マッチャーは両方を無視します。たとえば、java RegexDemo ".at(?x)#match hat, cat, and so on" matter
一連の文字の場合、mat
はパターンに一致します.at
。デフォルトでは、空白文字とコメントは許可されず、マッチャーはそれらを検索に含まれる文字として扱います。
(?s)
: ドット メタキャラクタが他の文字に加えて行区切り文字と一致する dotall モードを有効にします。たとえば、このコマンドはjava RegexDemo (?s). \n
改行文字を検索します。デフォルトは dotall の逆で、行区切り文字は検出されません。たとえば、コマンドではJava RegexDemo . \n
改行文字が見つかりません。
(?m)
:各行の^
先頭と末尾を一致させる複数行モードを有効にします。$
たとえば、java RegexDemo "(?m)^abc$" abc\nabc
入力テキスト内の両方のシーケンスを検索しますabc
。デフォルトでは、単一行モードが使用されます。^
入力テキスト全体の先頭と$
末尾が一致します。たとえば、java RegexDemo "^abc$" abc\nabc
一致するものがないという応答を返します。
(?u)
: Unicode を区別する大文字と小文字の位置合わせを有効にします。このフラグを と組み合わせて使用すると(?i)
、Unicode 標準に従って大文字と小文字を区別しないパターン マッチングが可能になります。デフォルト設定では、大文字と小文字が区別され、US-ASCII 文字のみが検索されます。
(?d)
: Unix スタイルの文字列モードを有効にします。このモードでは、マッチャーはコンテキスト内のメタ文字.
と^
行$
区切り文字のみを認識します\n
。デフォルトは非 Unix スタイルの文字列モードです。マッチャーは、上記のメタキャラクターのコンテキストで、すべての行区切り文字を認識します。
ネストされたフラグ式は、その文字が括弧のメタ文字で囲まれているため、キャプチャされたグループに似ています。キャプチャされたグループとは異なり、ネストされたフラグ式は非キャプチャ グループの例であり、テキスト文字をキャプチャしない正規表現構造です。これらは、括弧のメタキャラクターで囲まれた文字のシーケンスとして定義されます。
複数のネストされたフラグ式の指定 |
正規表現で複数のネストされたフラグ式を指定するには、フラグ式を並べて配置するか ( (?m)(?i)) )、フラグ式を定義する文字を連続して配置します ( (?mi) )。 |
結論
もうお気づきかと思いますが、正規表現は非常に便利で、構文の微妙な違いをマスターするとさらに便利になります。ここまで、正規表現と の基本を紹介してきました
Pattern
。パート 2 では、Regex API をさらに詳しく調べ、
Pattern
と
Matcher
のメソッドを調べます
PatternSyntaxException
。また、プログラムですぐに使用できる Regex API の実践的なアプリケーションを 2 つ紹介します。
Java の正規表現、パート 3 Java の正規表現、パート 4 Java の正規表現、パート 5
GO TO FULL VERSION