|
|
オプション修飾子 |
H.Kamifuji . |
修飾子を指定することで正規表現の基本的な動作を変更させることが出来ます。例えば大文字と小文字の区別を行わないようにマッチさせることも出来ます。ここではオプション修飾子の指定方法と使い方を確認していきます。 当ページでは、Linux CentOS7 の Gnome で動作テストしています。 現在(2021/08)では、JDK-16.0.2 にアップされています。一部、上位互換について、見直しを行っていきます。 現在(2021/11)では、JDK-17.0.1 にアップされています。一部、上位互換について、見直しを行っていきます。 現在(2023/04)では、JDK-20.0.1 にアップされています。一部、上位互換について、見直しを行っていきます。 現在(2024/10)では、JDK-23 にアップされています。一部、上位互換について、見直しを行っていきます。 |
|
修飾子を指定することで正規表現の基本動作を変更することができます。まずは修飾子の指定方法から確認していきます。 compileメソッドの引数に指定1つ目の方法はパターンオブジェクトを作成する時に、compileメソッドの引数に指定することです。compile public static Pattern compile(String regex, int flags)指定されたフラグを使用して、指定された正規表現をパターンにコンパイルします。 パラメータ: regex - コンパイルされる表現 flags - マッチフラグ。CASE_INSENSITIVE、MULTILINE、DOTALL、UNICODE_CASE、CANON_EQ、 UNIX_LINES、LITERAL、および COMMENTS を含めることのできるビットマスク 例外: IllegalArgumentException - 定義済みマッチフラグに対応するビット値以外の値が flags に設 定されている場合 PatternSyntaxException - 表現の構文が無効である場合 2番目の引数に修飾子を指定します。指定可能な値は次の通りです。 Pattern.CASE_INSENSITIVE 大文字と小文字を区別しないマッチングを有効にする Pattern.MULTILINE 複数行モードを有効にする Pattern.DOTALL DOTALL モードを有効にする Pattern.UNICODE_CASE Unicode に準拠した大文字と小文字を区別しないマッチングを有効にする Pattern.CANON_EQ 正規等価を有効にする Pattern.UNIX_LINES Unix ラインモードを有効にする Pattern.LITERAL パターンのリテラル構文解析を有効にする Pattern.COMMENTS パターン内で空白とコメントを使用できるようにする例えばPattern.CASE_INSENSITIVEを指定すると、大文字小文字を区別しないようになります。具体的には次のように記述します。 String regex = "good"; Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);各修飾子は同時に指定することが可能です。複数の修飾子を指定する場合は"|"で区切り続けて指定して下さい。具体的には次のように記述します。 String regex = "good"; Pattern p = Pattern.compile(regex, Pattern.MULTILINE | Pattern.DOTALL | Pattern.UNIX_LINES); 埋め込みフラグで指定2つ目の方法はパターンの中で埋め込みフラグを使用する方法です。埋め込みフラグは(?X)の形式で次のようなものが用意されています。(?i) Pattern.CASE_INSENSITIVE (?m) Pattern.MULTILINE (?s) Pattern.DOTALL (?u) Pattern.UNICODE_CASE (?d) Pattern.UNIX_LINES (?x) Pattern.COMMENTS例えば(?i)はcompileメソッドの引数でPattern.CASE_INSENSITIVEを指定したのと同じ意味を持ちます。 埋め込みフラグはパターンの中に記述します。例として次のように記述します。 "(?i)hello" "he(?i)llo"埋め込みフラグは記述された以降のパターンに効果が出ます。"(?i)hello"の場合はパターンの先頭に"(?i)"が記述されていますのでそれ以降の全てにおいて"(?i)"が有効です。よって次のような文字列にマッチします。 "hello" "Hello" "heLLo" "HELLO"それに対して"he(?i)llo"はパターンの途中に"(?i)"が記述されています。その為、このフラグが有効になるのは"llo"の部分だけです。よって次のような文字列にマッチします。 "hello" "heLLo" "hellO"また途中で埋め込みフラグの効果を無効にしたい場合は(?X)に対して(?-X)を記述します。例えば"(?i)"であれば"(?-i)"を使います。 "(?i)he(?-i)llo"この場合、"(?i)"から"(?-i)"までの部分に埋め込みフラグが有効となります。よって次のような文字列にマッチします。 "hello" "Hello" "HEllo"2つの方法のいずれかを使用することで正規表現の基本的な動作を変更することが可能です。では次のページ以降で各修飾子の使い方について確認していきます。 |
compileメソッドの引数としてPattern.CASE_INSENSITIVEを指定するか、埋め込みフラグで(?i)を使用するとパターンをマッチする時に大文字と小文字を区別しなくなります。 CASE_INSENSITIVE public static final int CASE_INSENSITIVE大文字と小文字を区別しないマッチングを有効にします。 デフォルトの大文字と小文字を区別しないマッチングでは、US-ASCII 文字セットの文字だけがマッチします。Unicode に準拠した大文字と小文字を区別しないマッチングを有効にするには、UNICODE_CASE フラグをこのフラグと組み合わせて指定します。 大文字と小文字を区別しないマッチングは、埋め込みフラグ表現 (?i) を使用して有効にすることもできます。 このフラグを指定すると、パフォーマンスがわずかに低下する場合があります。 次のように記述します。 String regex = "pattern"; Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);埋め込みフラグ表現 (?i)を使って次のようにパターン内に記述することもできます。 String regex = "(?i)pattern";具体的な例で考えてみます。次のようなパターンを定義しました。 "Test"ターゲット文字列毎に上記のパターンにマッチするかどうかの一覧が下記となります。 ○ Test × test × TEST × tesTでは先ほどのパターンに"(?i)"を付けます。 "(?i)Test""(?i)"が付けられると大文字と小文字を区別せずにマッチするかどうかを判断します。ターゲット文字列毎に上記のパターンにマッチするかどうかの一覧が下記となります。 ○ Test ○ test ○ TEST ○ tesTでは実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。/** * 大文字と小文字を区別しない */ import java.util.regex.Pattern; import java.util.regex.Matcher; class JSample2_1{ public static void main(String args[]){ String str1 = "Hello"; String str2 = "hello"; String str3 = "HELLO"; String regex1 = "hello"; Pattern p1 = Pattern.compile(regex1); String regex2 = "(?i)hello"; Pattern p2 = Pattern.compile(regex2); String regex3 = "hello"; Pattern p3 = Pattern.compile(regex3, Pattern.CASE_INSENSITIVE); System.out.println("パターン : " + regex1); check(p1, str1); check(p1, str2); check(p1, str3); System.out.println("パターン : " + regex2); check(p2, str1); check(p2, str2); check(p2, str3); System.out.println("\nPattern.compile(regex, Pattern.CASE_INSENSITIVE)"); System.out.println("パターン : " + regex3); check(p3, str1); check(p3, str2); check(p3, str3); } private static void check(Pattern p, String target){ Matcher m = p.matcher(target); if (m.find()){ System.out.println("○ " + target); }else{ System.out.println("× " + target); } } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Option]$ javac JSample2_1.java [xxxxxxxx@dddddddddd Option]$ java JSample2_1 パターン : hello × Hello ○ hello × HELLO パターン : (?i)hello ○ Hello ○ hello ○ HELLO Pattern.compile(regex, Pattern.CASE_INSENSITIVE) パターン : hello ○ Hello ○ hello ○ HELLO [xxxxxxxx@dddddddddd Option]$ |
compileメソッドの引数としてPattern.MULTILINEを指定するか、埋め込みフラグで(?m)を使用すると行末記号が有効となりメタ文字の"^"が行頭にマッチし、メタ文字の"$"行末記号の直前にもマッチするようになります。 MULTILINE public static final int MULTILINE複数行モードを有効にします。 複数行モードでは、表現 ^ と $ は、それぞれ行末記号または入力シーケンスの末尾の直後または直前にマッチします。デフォルトでは、これらの表現は入力シーケンス全体の先頭と末尾にだけマッチします。 複数行モードは、埋め込みフラグ表現 (?m) を使用して有効にすることもできます。 次のように記述します。 String regex = "pattern"; Pattern p = Pattern.compile(regex, Pattern.MULTILINE);埋め込みフラグ表現 (?m)を使って次のようにパターン内に記述することもできます。 String regex = "(?m)pattern";具体的な例で考えてみます。次のようなパターンを定義しました。 "^B"ターゲット文字列毎に上記のパターンにマッチするかどうかの一覧が下記となります。 ○ Book × Movie\nBookでは先ほどのパターンに"(?m)"を付けます。 "(?m)^B""(?m)"が付けられると行末記号を無視しなくなるため、メタ文字の"^"は文の先頭だけでなく行頭にもマッチします。またメタ文字の"$"は文の最後だけではなく行末文字の直前にマッチするようになります。ターゲット文字列毎に上記のパターンにマッチするかどうかの一覧が下記となります。 ○ Book ○ Movie\nBookでは実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。/** * 複数行モード */ import java.util.regex.Pattern; import java.util.regex.Matcher; class JSample3_1{ public static void main(String args[]){ String str1 = "Book"; String str2 = "Movie\nBook"; String regex1 = "^B"; Pattern p1 = Pattern.compile(regex1); String regex2 = "(?m)^B"; Pattern p2 = Pattern.compile(regex2); String regex3 = "^B"; Pattern p3 = Pattern.compile(regex3, Pattern.MULTILINE); System.out.println("パターン : " + regex1); check(p1, str1); check(p1, str2); System.out.println("パターン : " + regex2); check(p2, str1); check(p2, str2); System.out.println("\nPattern.compile(regex, Pattern.MULTILINE)"); System.out.println("パターン : " + regex3); check(p3, str1); check(p3, str2); } private static void check(Pattern p, String target){ Matcher m = p.matcher(target); if (m.find()){ System.out.println("○ " + target); }else{ System.out.println("× " + target); } } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Option]$ javac JSample3_1.java [xxxxxxxx@dddddddddd Option]$ java JSample3_1 パターン : ^B ○ Book × Movie Book パターン : (?m)^B ○ Book ○ Movie Book Pattern.compile(regex, Pattern.MULTILINE) パターン : ^B ○ Book ○ Movie Book [xxxxxxxx@dddddddddd Option]$ |
compileメソッドの引数としてPattern.DOTALLを指定するか、埋め込みフラグで(?s)を使用するとメタ文字の"."が行末記号にもマッチするようになります。 DOTALL public static final int DOTALLDOTALL モードを有効にします。 DOTALL モードでは、表現 . は行末記号を含む任意の文字にマッチします。デフォルトでは、この表現は行末記号にマッチしません。 DOTALL モードは、埋め込みフラグ表現 (?s) を使用して有効にすることもできます。(s は「single-line (単一行)」モードのニーモニック。Perl ではこう呼ばれている。) 次のように記述します。 String regex = "pattern"; Pattern p = Pattern.compile(regex, Pattern.DOTALL);埋め込みフラグ表現 (?s)を使って次のようにパターン内に記述することもできます。 String regex = "(?s)pattern";具体的な例で考えてみます。次のようなパターンを定義しました。 "width.height"ターゲット文字列毎に上記のパターンにマッチするかどうかの一覧が下記となります。 ○ width height × width\nheightでは先ほどのパターンに"(?s)"を付けます。 "(?s)width.height""(?s)"が付けられるとメタ文字の"."が行末記号にもマッチするようになります。ターゲット文字列毎に上記のパターンにマッチするかどうかの一覧が下記となります。 ○ width height ○ width\nheightでは実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。/** * DOTALLモード */ import java.util.regex.Pattern; import java.util.regex.Matcher; class JSample4_1{ public static void main(String args[]){ String str1 = "width height"; String str2 = "width\nheight"; String regex1 = "width.height"; Pattern p1 = Pattern.compile(regex1); String regex2 = "(?s)width.height"; Pattern p2 = Pattern.compile(regex2); String regex3 = "width.height"; Pattern p3 = Pattern.compile(regex3, Pattern.DOTALL); System.out.println("パターン : " + regex1); check(p1, str1); check(p1, str2); System.out.println("パターン : " + regex2); check(p2, str1); check(p2, str2); System.out.println("\nPattern.compile(regex, Pattern.DOTALL)"); System.out.println("パターン : " + regex3); check(p3, str1); check(p3, str2); } private static void check(Pattern p, String target){ Matcher m = p.matcher(target); if (m.find()){ System.out.println("○ " + target); }else{ System.out.println("× " + target); } } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Option]$ javac JSample4_1.java [xxxxxxxx@dddddddddd Option]$ java JSample4_1 パターン : width.height ○ width height × width height パターン : (?s)width.height ○ width height ○ width height Pattern.compile(regex, Pattern.DOTALL) パターン : width.height ○ width height ○ width height [xxxxxxxx@dddddddddd Option]$ |
compileメソッドの引数としてPattern.UNIX_LINESを指定するか、埋め込みフラグで(?d)を使用すると行末記号として扱われる文字が'\n'だけになります。 UNIX_LINES public static final int UNIX_LINESUnix ラインモードを有効にします。 このモードでは、'\n' 行末記号以外は、.、^、$ の動作で認識されません。 Unix ラインモードは、埋め込みフラグ表現 (?d) 使用して有効にすることもできます。 次のように記述します。 String regex = "pattern"; Pattern p = Pattern.compile(regex, Pattern.UNIX_LINES);埋め込みフラグ表現 (?d)を使って次のようにパターン内に記述することもできます。 String regex = "(?d)pattern";「行末記号」にも記載していますが、行末記号は'\n'の他に"\r\n"や'\r'などがあります。Unixラインモードを有効にすると行末記号として認識さえのが'\n'に限定されます。 具体的な例で考えてみます。次のようなパターンを定義しました。 "(?m)color$"複数行モードにしてありますので、メタ文字の"$"は行末記号に直前にマッチします。 ○ color ○ color\nalpha ○ color\r\nalphaでは先ほどのパターンに"(?d)"を付けます。 "(?m)(?d)color$""(?d)"が付けられると行末記号として扱われるのが"\n"だけになります。その結果、"\n"は行末記号して認識されますが"\r\n"は行末記号として認識されなくなるので、メタ文字の"$"が"\r\n"の直前にマッチしなくなります。ターゲット文字列毎に上記のパターンにマッチするかどうかの一覧が下記となります。 ○ color ○ color\nalpha × color\r\nalphaでは実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。/** * Unixラインモード */ import java.util.regex.Pattern; import java.util.regex.Matcher; class JSample5_1{ public static void main(String args[]){ String str1 = "abc"; String str2 = "abc\ndef"; String str3 = "abc\r\ndef"; String regex1 = "(?m)abc$"; Pattern p1 = Pattern.compile(regex1); String regex2 = "(?m)(?d)abc$"; Pattern p2 = Pattern.compile(regex2); String regex3 = "abc$"; Pattern p3 = Pattern.compile(regex3, Pattern.MULTILINE | Pattern.UNIX_LINES); System.out.println("パターン : " + regex1); check(p1, str1); check(p1, str2); check(p1, str3); System.out.println("パターン : " + regex2); check(p2, str1); check(p2, str2); check(p2, str3); System.out.println("\nPattern.compile(regex, Pattern.MULTILINE | Pattern.UNIX_LINES)"); System.out.println("パターン : " + regex3); check(p3, str1); check(p3, str2); check(p3, str3); } private static void check(Pattern p, String target){ Matcher m = p.matcher(target); if (m.find()){ System.out.println("○ " + target); }else{ System.out.println("× " + target); } } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Option]$ javac JSample5_1.java [xxxxxxxx@dddddddddd Option]$ java JSample5_1 パターン : (?m)abc$ ○ abc ○ abc def ○ abc def パターン : (?m)(?d)abc$ ○ abc ○ abc def × abc def Pattern.compile(regex, Pattern.MULTILINE | Pattern.UNIX_LINES) パターン : abc$ ○ abc ○ abc def × abc def [xxxxxxxx@dddddddddd Option]$ |
compileメソッドの引数としてPattern.COMMENTSを指定するか、埋め込みフラグで(?x)を使用するとパターンの中で空白とコメントを使用することができるようになります。 COMMENTS public static final int COMMENTSパターン内で空白とコメントを使用できるようにします。 このモードでは、空白は無視され、# で始まる埋め込みコメントは行末まで無視されます。 コメントモードは、埋め込みフラグ表現 (?x) を使用して有効にすることもできます。 次のように記述します。 String regex = "pattern"; Pattern p = Pattern.compile(regex, Pattern.COMMENTS);埋め込みフラグ表現 (?x)を使って次のようにパターン内に記述することもできます。 String regex = "(?x)pattern";このモードを有効にするとコメント内に空白や改行を入れても無視されます。 具体的な例で考えてみます。次のようなパターンを定義しました。 "(red|blue)(point|line)"ではパターンに"(?x)"を付けてパターンを整形します。 "(?x)(red|blue) (point|line)"上記のようにパターン内に空白を入れても無視されます。 "(?x) \n" + "(red|blue) \n" + "(point|line) \n"上記のようにパターン内に改行を入れても無視されます。 Javaの場合は複数行の文字列を定義できないので注意して下さい。また"#"をパターンの中に記述すると、"#"から行末まではコメントとして扱われます。 "(?x) \n" + "(red|blue) # 赤 or 青 \n" + "(point|line)" # 点 or 線" #から行末までがコメントなので、最後に改行文字を入れるのを忘れないで下さい。このように空白や改行、そしてコメントをパターン内に記述することで、複雑なパターンについて解説を加えておくことができます。 では実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。/** * パターン内で空白とコメントを使用 */ import java.util.regex.Pattern; import java.util.regex.Matcher; class JSample6_1{ public static void main(String args[]){ String str1 = "Watch 3500yen"; String str2 = "Apple 280yen"; String str3 = "1350year"; String regex1 = "(?x)" + "( \n" + " ( \n" + " \\d #任意の数字 \n" + " + #1回以上繰り返し \n" + " ) \n" + " ( \n" + " yen #yenで終わる \n" + " ) \n" + " )"; Pattern p1 = Pattern.compile(regex1); String regex2 = "( \n" + " ( \n" + " \\d #任意の数字 \n" + " + #1回以上繰り返し \n" + " ) \n" + " ( \n" + " yen #yenで終わる \n" + " ) \n" + " )"; Pattern p2 = Pattern.compile(regex2, Pattern.COMMENTS); System.out.println("パターン : " + regex1); check(p1, str1); check(p1, str2); check(p1, str3); System.out.println("\nPattern.compile(regex, Pattern.COMMENTS)"); System.out.println("パターン : " + regex2); check(p2, str1); check(p2, str2); check(p2, str3); } private static void check(Pattern p, String target){ Matcher m = p.matcher(target); if (m.find()){ System.out.println("○ " + target); }else{ System.out.println("× " + target); } } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Option]$ javac JSample6_1.java [xxxxxxxx@dddddddddd Option]$ java JSample6_1 パターン : (?x)( ( \d #任意の数字 + #1回以上繰り返し ) ( yen #yenで終わる ) ) ○ Watch 3500yen ○ Apple 280yen × 1350year Pattern.compile(regex, Pattern.COMMENTS) パターン : ( ( \d #任意の数字 + #1回以上繰り返し ) ( yen #yenで終わる ) ) ○ Watch 3500yen ○ Apple 280yen × 1350year [xxxxxxxx@dddddddddd Option]$ |
compileメソッドの引数としてPattern.UNICODE_CASEを指定するか、埋め込みフラグで(?u)を使用すると非ASCIIのUnicode文字の大文字と小文字を区別しなくなります。 UNICODE_CASE public static final int UNICODE_CASEUnicode に準拠した大文字と小文字を区別しないマッチングを有効にします。 このフラグと CASE_INSENSITIVE フラグを同時に指定した場合は、Unicode 標準に準拠した大文字と小文字を区別しないマッチングが行われます。デフォルトの大文字と小文字を区別しないマッチングでは、US-ASCII 文字セットの文字だけがマッチします。 Unicode に準拠した大文字と小文字を区別しないマッチングは、埋め込みフラグ表現 (?u) を使用して有効にすることもできます。 このフラグを指定すると、パフォーマンスが低下する場合があります。 次のように記述します。 String regex = "pattern"; Pattern p = Pattern.compile(regex, Pattern.UNICODE_CASE);埋め込みフラグ表現 (?u)を使って次のようにパターン内に記述することもできます。 String regex = "(?u)pattern";このオプション修飾子を使用する場合はあわせてCASE_INSENSITIVEを同時に指定することで、非ASCII文字の大文字と小文字を区別しなくなります。例えば全角の"A"と"a"を区別せずにマッチします。 具体的な例で考えてみます。次のようなパターンを定義しました。 "Ant"ターゲット文字列毎に上記のパターンにマッチするかどうかの一覧が下記となります。 ○ Ant × ant × ANTでは先ほどのパターンに"(?i)"と"(?u)"を付けます。 "(?i)(?u)Ant""(?i)"が付けられると大文字と小文字を区別せずにマッチするかどうかを判断します。そして"(?u)"が付けられると非ASCII文字にも適用されるようになります。ターゲット文字列毎に上記のパターンにマッチするかどうかの一覧が下記となります。 ○ Ant ○ ant ○ ANTでは実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。/** * Unicodeに準拠した大文字と小文字を区別しない */ import java.util.regex.Pattern; import java.util.regex.Matcher; class JSample7_1{ public static void main(String args[]){ String str1 = "ANT"; String str2 = "ant"; String regex1 = "ant"; Pattern p1 = Pattern.compile(regex1); String regex2 = "(?u)ant"; Pattern p2 = Pattern.compile(regex2); String regex3 = "(?i)ant"; Pattern p3 = Pattern.compile(regex3); String regex4 = "(?i)(?u)ant"; Pattern p4 = Pattern.compile(regex4); String regex5 = "ant"; Pattern p5 = Pattern.compile(regex5, Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE); System.out.println("パターン : " + regex1); check(p1, str1); check(p1, str2); System.out.println("パターン : " + regex2); check(p2, str1); check(p2, str2); System.out.println("パターン : " + regex3); check(p3, str1); check(p3, str2); System.out.println("パターン : " + regex4); check(p4, str1); check(p4, str2); System.out.println("\nPattern.compile(regex, Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE)"); System.out.println("パターン : " + regex5); check(p5, str1); check(p5, str2); } private static void check(Pattern p, String target){ Matcher m = p.matcher(target); if (m.find()){ System.out.println("○ " + target); }else{ System.out.println("× " + target); } } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Option]$ javac JSample7_1.java [xxxxxxxx@dddddddddd Option]$ java JSample7_1 パターン : ant × ANT ○ ant パターン : (?u)ant × ANT ○ ant パターン : (?i)ant × ANT ○ ant パターン : (?i)(?u)ant ○ ANT ○ ant Pattern.compile(regex, Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE) パターン : ant ○ ANT ○ ant [xxxxxxxx@dddddddddd Option]$ |
compileメソッドの引数としてPattern.LITERALを指定するとパターンのリテラル構文解析を有効になります。 LITERAL public static final int LITERALパターンのリテラル構文解析を有効にします。 このフラグが指定されている場合、パターンを指定する入力文字列は、リテラル文字のシーケンスとして処理されます。入力シーケンス内のメタキャラクタまたはエスケープシーケンスに、特別な意味はありません。 CASE_INSENSITIVE および UNICODE_CASE フラグをこのフラグとともに使用すると、マッチングに対する影響が維持されます。ほかのフラグは不要になります。 リテラル構文解析を有効にするための埋め込みフラグ文字はありません。 次のように記述します。 String regex = "pattern"; Pattern p = Pattern.compile(regex, Pattern.LITERAL);このオプション修飾子を使用するとパターン内のメタ文字などは特別な意味を持たなくなります。 具体的な例で考えてみます。次のようなパターンを定義しました。 "\d+"数字が1文字以上続く場合にマッチします。ターゲット文字列毎に上記のパターンにマッチするかどうかの一覧が下記となります。 ○ 100 ○ old20 × \d+今度は同じパターンでPattern.LITERALを指定してみます。"\d"や"+"は特別な意味を持たなくなるため、マッチするのは文字列としての"\d+"だけです。 × 100 × old20 ○ \d+では実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。/** * パターンのリテラル構文解析を有効にする */ import java.util.regex.Pattern; import java.util.regex.Matcher; class JSample8_1{ public static void main(String args[]){ String str1 = "100"; String str2 = "old20"; String str3 = "\\d+"; String regex1 = "\\d+"; Pattern p1 = Pattern.compile(regex1); String regex2 = "\\d+"; Pattern p2 = Pattern.compile(regex2, Pattern.LITERAL); System.out.println("パターン : " + regex1); check(p1, str1); check(p1, str2); check(p1, str3); System.out.println("\nPattern.compile(regex, Pattern.LITERAL)"); System.out.println("パターン : " + regex2); check(p2, str1); check(p2, str2); check(p2, str3); } private static void check(Pattern p, String target){ Matcher m = p.matcher(target); if (m.find()){ System.out.println("○ " + target); }else{ System.out.println("× " + target); } } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Option]$ javac JSample8_1.java [xxxxxxxx@dddddddddd Option]$ java JSample8_1 パターン : \d+ ○ 100 ○ old20 × \d+ Pattern.compile(regex, Pattern.LITERAL) パターン : \d+ × 100 × old20 ○ \d+ [xxxxxxxx@dddddddddd Option]$ |
|