|
|
|||||||||||||||||||||||||||||
| 任意の文字と繰り返し(量指定子) |
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 にアップされています。一部、上位互換について、見直しを行っていきます。 |
|
|
|
メタ文字の1つであるドット"."をパターンの中に記述すると行末記号を除く任意の一文字にマッチします。 書式は次の通りです。 "." メタ文字の"."は繰り返しではなく文字クラスの一つですが、説明の都合上ここに記載しています。使用例としては次のようになります。 "ab.cd"上記の場合、ドット(.)は任意の一文字にマッチしますので"abfcd"や"ab0cd"などドット(.)が記述された位置にどんな文字(行末記号は除く)が書かれている場合もマッチすることになります。(行末記号については「行末記号」を参照して下さい)。 注意する点としては任意の一文字ですので必ず一文字必要です。よって"abcd"のように"ab"と"cd"の間に文字が存在しないものや、「abeecd」のように「ab」と「cd」の間に2つ以上の文字が含まれる場合はマッチしません。 ○ abhcd ○ ab4cd ○ ab#cd × abcd × abppcd"."はパターン内で何回でも使用することが出来ますので次のように記述することもできます。 "ab..cd"上記の場合は"ab"と"cd"の間に任意の二文字がある文字列にマッチします。(例:abomcdd)。 "a.b.c.d"上記の場合は"a","b","c","d"の各文字の間に1つずつ任意の文字がある文字列にマッチします。(例:a1b2c3d)。 具体的には次のように記述します。
String str = "abcd";
String regex = "a.c";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
if (m.find()){
System.out.println("マッチしました");
}else{
System.out.println("マッチしません");
}
上記の場合はマッチします。DOTALLモードデフォルトでは"."は行末記号にマッチしませんが、DOTALLモードを有効にすると"."は行末記号にもマッチするようになります。具体的な例で考えてみます。パターンを"b.c"とした場合、デフォルトでは"ab\ncd"にはマッチしませんが、DOTALLモードを有効にするとマッチするようになります。
デフォルトの状態: 具体的には次のように記述します。
String str = "ab\ncd";
String regex = "b.c";
Pattern p = Pattern.compile(regex, Pattern.DOTALL);
Matcher m = p.matcher(str);
if (m.find()){
System.out.println("マッチしました");
}else{
System.out.println("マッチしません");
}
では実際に試してみます。サンプルプログラム下記のサンプルを実行してみよう。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class JSample1_1{
public static void main(String args[]){
String str1 = "abcd";
String str2 = "abMcd";
String str3 = "abKMcd";
String str4 = "ab\ncd";
String regex1 = "b.c";
Pattern p1 = Pattern.compile(regex1);
String regex2 = "b.c";
Pattern p2 = Pattern.compile(regex2, Pattern.DOTALL);
System.out.println("パターン : " + regex1);
check(p1, str1);
check(p1, str2);
check(p1, str3);
check(p1, str4);
System.out.println("\nDOTALLモードに変更\n");
System.out.println("パターン : " + regex2);
check(p2, str1);
check(p2, str2);
check(p2, str3);
check(p2, str4);
}
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 Repeat]$ javac JSample1_1.java [xxxxxxxx@dddddddddd Repeat]$ java JSample1_1 パターン : b.c × abcd ○ abMcd × abKMcd × ab cd DOTALLモードに変更 パターン : b.c × abcd ○ abMcd × abKMcd ○ ab cd [xxxxxxxx@dddddddddd Repeat]$デフォルトのままですと"."は行末記号にマッチしませんが、DOTALLモードを有効にすると行末記号にもマッチしていることが確認できます。 |
|
量指定子を使う場合の考え方を先に確認しておきます。 例として"+"を使って考えます。"+"は直前の文字が1回以上繰り返す場合にマッチするメタ文字です。例として次のようなパターンを考えてみます。 "ab+"上記のパターンの場合、"a"で始まり"b"が1回以上続く場合にマッチします。例えば次のような文字にマッチします。 ○ abc ○ abbc ○ abbbbcここでターゲットとなる文字列のどの部分にマッチしたかを考えます。単に"+"と記載した場合は最長一致数量子と呼ばれるもので、最も長い部分にマッチします。つまり先ほどの例でどの部分にマッチしたのかを記述すると次の部分にマッチしています。 [ab]c [abb]c [abbbb]cそれに対して"+?"は直前の文字が1回以上繰り返す場合にマッチするメタ文字とう点では同じですが最短一致数量子と呼ばれるものです。最短一致数量子は最も短い部分にマッチします。 "ab+?"先ほどと同じターゲット文字列にマッチさせた場合、どの部分にマッチしたのかを記述すると次の部分にマッチします。 [ab]c [ab]bc [ab]bbbcこのように最長一致数量子である"+"でも最短一致数量子である"+?"でも直前の文字を1回以上繰り返すものにマッチするという意味では同じなのですが、マッチする部分が異なってきます。 強欲な数量子多くのプログラミング言語では最長一致数量子と最短一致数量子しかありませんが、Javaにおいては強欲な数量子(又は絶対最大指定子)と呼ばれるものがあります。例えば任意の一文字を表す"."を1回以上繰り返すようなパターンを記述してみます。 ".+g"上記の場合、任意の1文字が1回以上続き、最後に"g"が出現する場合にマッチします。 では次のようなターゲット文字列を対象にマッチさせてみます。 abcdefg上記は任意の文字が1回以上続いた後に"g"が出ているのでマッチします。この時"+"は最長一致数量子でありできるだけ長い部分にマッチしようとします。そこでパターン野中で".+"は"abcdefg"全体にマッチしようとします。 abcdefg ------- .+ gただ".+"の部分で全体にマッチさせてしまうとパターンの最後の"g"がマッチせず、パターン全体としてはマッチしなくなってしまいます。そこで".+"の部分は"abcdefg"ではなく"abcdef"にマッチします。 abcdef g ------ - .+ gこの結果、パターン全体の".+g"はターゲット文字列にマッチします。"+"はできるだけ長い部分にマッチしようとしますが、パターン全体がマッチすることを優先し、マッチする部分を減らして調整するということです。 次に強欲な数量子(又は絶対最大指定子)を使う場合を考えてみます。"++"は"+"の強欲な数量子バージョンです。次のように記述することができます。 ".++g"強欲な数量子の特徴は、パターン全体がマッチするかどうかは考慮せず、とにかく一番長い部分にマッチしようとする点です。 では次のようなターゲット文字列を対象にマッチさせてみます。 abcdefgパターの中で".++"の部分は任意の文字が1文字以上続く場合にマッチしますので、ターゲット文字列全体の"abcdefg"にマッチします。 abcdefg ------- .++ gパターンの中で残っている"g"にマッチする部分がターゲット文字列には残っていない為、結果的にパターン全体の".++g"はマッチしなくなります。 このようにJavaでは1つの量指定子に対して3つの種類が用意されています。最長一致数量子と最短一致数量子ではマッチする部分が違うだけですが、強欲な数量子(又は絶対最大指定子)の場合はマッチそのものがしなくなる場合もありますので注意して下さい。 では実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class JSample2_1{
public static void main(String args[]){
String str1 = "abc";
String str2 = "abbc";
String str3 = "abbbbc";
String regex1 = "ab+";
Pattern p1 = Pattern.compile(regex1);
String regex2 = "ab+?";
Pattern p2 = Pattern.compile(regex2);
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);
}
private static void check(Pattern p, String target){
Matcher m = p.matcher(target);
if (m.find()){
int start = m.start();
int end = m.end();
String str = target.substring(0, start) + "[" + m.group() + "]"
+ target.substring(end, target.length());
System.out.println("○ " + str);
}else{
System.out.println("× " + target);
}
}
}
上記をコンパイルした後で実行すると次のように表示されます。[xxxxxxxx@dddddddddd Repeat]$ javac JSample2_1.java [xxxxxxxx@dddddddddd Repeat]$ java JSample2_1 パターン : ab+ ○ [ab]c ○ [abb]c ○ [abbbb]c パターン : ab+? ○ [ab]c ○ [ab]bc ○ [ab]bbbc [xxxxxxxx@dddddddddd Repeat]$このサンプルでは最長一致数量子と最短一致数量子でマッチする部分がどのように違うのかを表示しています。 もう一つサンプルを試してみます。 サンプルプログラム下記のサンプルを実行してみよう。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class JSample2_2{
public static void main(String args[]){
String str1 = "abbc";
String str2 = "abbbbc";
String str3 = "abbbbbbc";
String regex1 = "ab+b";
Pattern p1 = Pattern.compile(regex1);
String regex2 = "ab++b";
Pattern p2 = Pattern.compile(regex2);
String regex3 = "ab++c";
Pattern p3 = Pattern.compile(regex3);
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("パターン : " + 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()){
int start = m.start();
int end = m.end();
String str = target.substring(0, start) + "[" + m.group() + "]"
+ target.substring(end, target.length());
System.out.println("○ " + str);
}else{
System.out.println("× " + target);
}
}
}
上記をコンパイルした後で実行すると次のように表示されます。[xxxxxxxx@dddddddddd Repeat]$ javac JSample2_2.java [xxxxxxxx@dddddddddd Repeat]$ java JSample2_2 パターン : ab+b ○ [abb]c ○ [abbbb]c ○ [abbbbbb]c パターン : ab++b × abbc × abbbbc × abbbbbbc パターン : ab++c ○ [abbc] ○ [abbbbc] ○ [abbbbbbc] [xxxxxxxx@dddddddddd Repeat]$このサンプルでは最長一致数量子と強欲な数量子でマッチするかどうかに違いが出てくるのを分かるようにしています。 |
|
メタ文字の1つである"*"をパターンの中に記述すると"*"の直前にある文字が0回以上繰り返された文字列にマッチします。0回でも可なので直前の文字が存在しなくてもマッチします。 書式は次の通りです。 "X*" 最長一致数量子 "X*?" 最短一致数量子 "X*+" 強欲な数量子※ 3つの種類の違いについては「最長一致数量子/最短一致数量子/強欲な数量子」を参照して下さい。以降は最長一致数量子について解説します。 "X*"は直前の文字である"X"が0回以上繰り返したものにマッチします。0回以上というのは"X"が無い場合と"X"や"XXXXX"など"X"が1回以上繰り返されている文字マッチするということになります。(直前の文字が無い場合は、空文字にマッチしていることになります)。 例としてパターン"aX*b"がどのようなターゲット文字列の場合にマッチするかしないかは次のようになります。 パターン "aX*b" ○ ab ○ aXb ○ aXXXb ○ aXXXXXXb × aYb具体的には次のように記述します。
String str = "boolean";
String regex = "bo*l";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
if (m.find()){
System.out.println("マッチしました");
}else{
System.out.println("マッチしません");
}
上記の場合、"b"+"o"が0回以上+"l"となりますのでマッチします。では実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class JSample3_1{
public static void main(String args[]){
String str1 = "bl";
String str2 = "bol";
String str3 = "boool";
String str4 = "baool";
String str5 = "boolean";
String regex = "bo*l";
Pattern p = Pattern.compile(regex);
System.out.println("パターン : " + regex);
check(p, str1);
check(p, str2);
check(p, str3);
check(p, str4);
check(p, str5);
}
private static void check(Pattern p, String target){
Matcher m = p.matcher(target);
if (m.find()){
System.out.println("○ " + target + " [" + m.group() + "]");
}else{
System.out.println("× " + target);
}
}
}
上記をコンパイルした後で実行すると次のように表示されます。[xxxxxxxx@dddddddddd Repeat]$ javac JSample3_1.java [xxxxxxxx@dddddddddd Repeat]$ java JSample3_1 パターン : bo*l ○ bl [bl] ○ bol [bol] ○ boool [boool] × baool ○ boolean [bool] [xxxxxxxx@dddddddddd Repeat]$ |
|
メタ文字の1つである"+"をパターンの中に記述すると"+"の直前にある文字が1回以上繰り返された文字列にマッチします。 書式は次の通りです。 "X+" 最長一致数量子 "X+?" 最短一致数量子 "X++" 強欲な数量子※ 3つの種類の違いについては「最長一致数量子/最短一致数量子/強欲な数量子」を参照して下さい。以降は最長一致数量子について解説します。 "X+"は直前の文字である"X"が1回以上繰り返したものにマッチします。1回以上というのは"X"や"XXX"など"X"が1回以上繰り返されている文字マッチするということになります。"*"と異なり1回も出現しない場合はマッチしません。 例としてパターン"aX+b"がどのようなターゲット文字列の場合にマッチするかしないかは次のようになります。 パターン "aX+b" × ab ○ aXb ○ aXXXb ○ aXXXXXXb × aYb具体的には次のように記述します。
String str = "boolean";
String regex = "bo+l";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
if (m.find()){
System.out.println("マッチしました");
}else{
System.out.println("マッチしません");
}
上記の場合、"b"+"o"が1回以上+"l"となりますのでマッチします。では実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class JSample4_1{
public static void main(String args[]){
String str1 = "bl";
String str2 = "bol";
String str3 = "boool";
String str4 = "baool";
String str5 = "boolean";
String regex = "bo+l";
Pattern p = Pattern.compile(regex);
System.out.println("パターン : " + regex);
check(p, str1);
check(p, str2);
check(p, str3);
check(p, str4);
check(p, str5);
}
private static void check(Pattern p, String target){
Matcher m = p.matcher(target);
if (m.find()){
System.out.println("○ " + target + " [" + m.group() + "]" );
}else{
System.out.println("× " + target);
}
}
}
上記をコンパイルした後で実行すると次のように表示されます。[xxxxxxxx@dddddddddd Repeat]$ javac JSample4_1.java [xxxxxxxx@dddddddddd Repeat]$ java JSample4_1 パターン : bo+l × bl ○ bol [bol] ○ boool [boool] × baool ○ boolean [bool] [xxxxxxxx@dddddddddd Repeat]$ |
|
メタ文字の1つである"?"をパターンの中に記述すると"?"の直前にある文字が0回か1回現れる文字列にマッチします。 書式は次の通りです。 "X?" 最長一致数量子 "X??" 最短一致数量子 "X?+" 強欲な数量子※ 3つの種類の違いについては「最長一致数量子/最短一致数量子/強欲な数量子」を参照して下さい。以降は最長一致数量子について解説します。 "X?"は直前の文字である"X"が0回か1回以上現れるものにマッチします。0回というのは"X"が無い場合、1回というのは"X"です。(直前の文字が無い場合は、空文字にマッチしていることになります)。 例としてパターン"aX?b"がどのようなターゲット文字列の場合にマッチするかしないかは次のようになります。 パターン "aX?b" ○ ab ○ aXb × aXXXb × aXXXXXXb × aYb具体的には次のように記述します。
String str = "boolean";
String regex = "bo?l";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
if (m.find()){
System.out.println("マッチしました");
}else{
System.out.println("マッチしません");
}
上記の場合、"b"+"o"が0回か1回+"l"となりますのでマッチしません。では実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class JSample5_1{
public static void main(String args[]){
String str1 = "bl";
String str2 = "bol";
String str3 = "boool";
String str4 = "baool";
String str5 = "boolean";
String regex = "bo?l";
Pattern p = Pattern.compile(regex);
System.out.println("パターン : " + regex);
check(p, str1);
check(p, str2);
check(p, str3);
check(p, str4);
check(p, str5);
}
private static void check(Pattern p, String target){
Matcher m = p.matcher(target);
if (m.find()){
System.out.println("○ " + target + " [" + m.group() + "]");
}else{
System.out.println("× " + target);
}
}
}
上記をコンパイルした後で実行すると次のように表示されます。[xxxxxxxx@dddddddddd Repeat]$ javac JSample5_1.java [xxxxxxxx@dddddddddd Repeat]$ java JSample5_1 パターン : bo?l ○ bl [bl] ○ bol [bol] × boool × baool × boolean [xxxxxxxx@dddddddddd Repeat]$ |
|
直前の文字を指定した回数だけ繰り返された場合にマッチするパターンを定義する方法を確認します。 回数を指定まず回数を指定する場合です。書式は次の通りです。
"X{n}" 最長一致数量子
"X{n}?" 最短一致数量子
"X{n}+" 強欲な数量子
※ 3つの種類の違いについては「最長一致数量子/最短一致数量子/強欲な数量子」を参照して下さい。以降は最長一致数量子について解説します。"X{n}"は直前の文字である"X"がn回現れるものにマッチします。 例としてパターン"aX{3}b"がどのようなターゲット文字列の場合にマッチするかしないかは次のようになります。
パターン "aX{3}b"
× ab
× aXb
○ aXXXb
× aXXXXXXb
× aYb
マッチするのは"aXXXb"が含まれる文字列だけです。指定した回数以上次に指定した回数以上繰り返し現れる場合です。書式は次の通りです。
"X{n,}" 最長一致数量子
"X{n,}?" 最短一致数量子
"X{n,}+" 強欲な数量子
"X{n,}"は直前の文字である"X"がn回以上現れるものにマッチします。例としてパターン"aX{3,}b"がどのようなターゲット文字列の場合にマッチするかしないかは次のようになります。
パターン "aX{3,}b"
× ab
× aXb
○ aXXXb
○ aXXXXXXb
× aYb
マッチするのは"aXXXb"や"aXXXXXb"などのように"a"と"b"の間に"X"が3回以上繰り返される文字列だけです。範囲を指定次に繰り返される範囲を指定する場合です。書式は次の通りです。
"X{n,m}" 最長一致数量子
"X{n,m}?" 最短一致数量子
"X{n,m}+" 強欲な数量子
"X{n,m}"は直前の文字である"X"がn回以上m回以下の回数現れるものにマッチします。例としてパターン"aX{3,5}b"がどのようなターゲット文字列の場合にマッチするかしないかは次のようになります。
パターン "aX{3,5}b"
× ab
× aXb
○ aXXXb
○ aXXXXb
○ aXXXXXb
× aXXXXXXb
× aYb
マッチするのは"aXXXb"、"aXXXXb"、"aXXXXXb"だけです。具体的には次のように記述します。
String str = "boolean";
String regex = "bo{2,4}l";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
if (m.find()){
System.out.println("マッチしました");
}else{
System.out.println("マッチしません");
}
上記の場合、"b"+"o"が2回以上4回以下+"l"となりますのでマッチします。では実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class JSample6_1{
public static void main(String args[]){
String str1 = "bl";
String str2 = "bol";
String str3 = "bool";
String str4 = "boool";
String str5 = "booool";
String regex1 = "bo{2}l";
Pattern p1 = Pattern.compile(regex1);
String regex2 = "bo{2,}l";
Pattern p2 = Pattern.compile(regex2);
String regex3 = "bo{2,3}l";
Pattern p3 = Pattern.compile(regex3);
System.out.println("パターン : " + regex1);
check(p1, str1);
check(p1, str2);
check(p1, str3);
check(p1, str4);
check(p1, str5);
System.out.println("パターン : " + regex2);
check(p2, str1);
check(p2, str2);
check(p2, str3);
check(p2, str4);
check(p2, str5);
System.out.println("パターン : " + regex3);
check(p3, str1);
check(p3, str2);
check(p3, str3);
check(p3, str4);
check(p3, str5);
}
private static void check(Pattern p, String target){
Matcher m = p.matcher(target);
if (m.find()){
System.out.println("○ " + target + " [" + m.group() + "]" );
}else{
System.out.println("× " + target);
}
}
}
上記をコンパイルした後で実行すると次のように表示されます。
[xxxxxxxx@dddddddddd Repeat]$ javac JSample6_1.java
[xxxxxxxx@dddddddddd Repeat]$ java JSample6_1
パターン : bo{2}l
× bl
× bol
○ bool [bool]
× boool
× booool
パターン : bo{2,}l
× bl
× bol
○ bool [bool]
○ boool [boool]
○ booool [booool]
パターン : bo{2,3}l
× bl
× bol
○ bool [bool]
○ boool [boool]
× booool
[xxxxxxxx@dddddddddd Repeat]$
|
|
メタ文字の"*"、"+"、"?"及び範囲を指定する{n,m}を使用する場合、繰り返しの対象はメタ文字の直前の一文字だけでした。ここでは一文字ではなく複数の文字を1つのグループとして扱い、複数の文字を繰り返しの対象にする方法を確認します。 複数の文字を対象にするには、複数の文字を()で囲みグループにします。記述方法は次のようになります。 (複数の文字)メタ文字※ 括弧は量指定子のためのグループ化以外にも使用されます。 上記では「(」から「)」で囲まれた文字列全体が繰り返しの対象となります。メタ文字には"*"や"+"などが指定できます。例えば"bye"と言う3つの文字が1回以上繰り返されて現れた場合にマッチする正規表現は次の通りです。 "a(bye)+b"上記の場合、「(」から「)」で囲まれた間に書かれた文字が1つのグループとなります。そしてメタ文字の"+"は直前にある文字が1回以上繰り返された場合にマッチしますが、今回は直前の文字がグループなのでグループの中の複数の文字が1回以上繰り返された場合にマッチします。 ○ abyeb ○ abyebyeb ○ abyebyebyebグループ化を用いることで、文字の集まりである文字列を対象とした繰り返しをパターンとして定義することが出来ます。 では実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class JSample7_1{
public static void main(String args[]){
String str1 = "bananaba";
String str2 = "banaba";
String str3 = "baneba";
String regex1 = "a(na)+b";
Pattern p1 = Pattern.compile(regex1);
System.out.println("パターン : " + regex1);
check(p1, str1);
check(p1, str2);
check(p1, str3);
}
private static void check(Pattern p, String target){
Matcher m = p.matcher(target);
if (m.find()){
System.out.println("○ " + target + " [" + m.group() + "]" );
}else{
System.out.println("× " + target);
}
}
}
上記をコンパイルした後で実行すると次のように表示されます。[xxxxxxxx@dddddddddd Repeat]$ javac JSample7_1.java [xxxxxxxx@dddddddddd Repeat]$ java JSample7_1 パターン : a(na)+b ○ bananaba [ananab] ○ banaba [anab] × baneba [xxxxxxxx@dddddddddd Repeat]$ |
|
任意の一文字にマッチするメタ文字"."と量指定子であるメタ文字"*"や"+"を組み合わせることで、任意の文字が繰り返し現れた場合にマッチするパターンを作成することが出来ます。 例として"'"と"'"の間に任意の文字が繰り返し現れるパターンは次のようになります。 "'.+'"上記の場合、メタ文字"+"の直前の文字がメタ文字"."となっています。"+"は直前の文字を1回以上繰り返す場合にマッチし、"."は任意の一文字にマッチします。結果として".+"は任意の文字が1回以上繰り返す場合にマッチすることになります。よって"'"と"'"の間にどんな文字が何文字記述されていてもマッチすることになります。 ○ abc'def'ghi ○ my namae is 'ken'ただし、どの部分にマッチするかについては十分に注意する必要があります。 One 'Hamburger' and a 'Coffee' please上記の文字列に対して"'.+'"がマッチする可能性があるのは「'Hamburger'」「'Hamburger' and a '」「'Hamburger' and a 'Coffee'」などがあります。いずれも"'"から始まり、任意の文字が1文字以上続き、"'"で終わっています。マッチするかどうかだけを調べるのではなく、どこにマッチするのかが重要な場合は十分な注意が必要です。 では実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class JSample8_1{
public static void main(String args[]){
String str1 = "My name is 'Tanaka' 'kamifuji' ";
String str2 = "your 'first' name";
String str3 = "I'm a student";
String regex1 = "'.+'";
Pattern p1 = Pattern.compile(regex1);
System.out.println("パターン : " + regex1);
check(p1, str1);
check(p1, str2);
check(p1, str3);
}
private static void check(Pattern p, String target){
Matcher m = p.matcher(target);
if (m.find()){
System.out.println("○ " + target + " [" + m.group() + "]" );
}else{
System.out.println("× " + target);
}
}
}
上記をコンパイルした後で実行すると次のように表示されます。[xxxxxxxx@dddddddddd Repeat]$ javac JSample8_1.java [xxxxxxxx@dddddddddd Repeat]$ java JSample8_1 パターン : '.+' ○ My name is 'Tanaka' 'kamifuji' ['Tanaka' 'kamifuji'] ○ your 'first' name ['first'] × I'm a student [xxxxxxxx@dddddddddd Repeat]$ |
|