MULTILINEフラグ(複数行モードを有効にする)

Java の正規表現で利用可能なフラグの一つである MULTILINE フラグの使い方です。 MULTILINE フラグを有効にすると、メタ文字であるキャレット(^)とドル記号($)が文字列の先頭と末尾以外の位置にある行末記号にもマッチするようになります。ここでは Java の正規表現における MULTILINE フラグの使い方について解説します。

(Last modified: )

MULTILINEフラグを有効にする

MULTILINE フラグは Java で利用可能なフラグの一つで、有効にすることでメタ文字であるキャレット(^)とドル記号($)が文字列の先頭と末尾以外の位置にある行末記号にもマッチするようになります。(行末記号とは \n などの行の末尾を表す文字です。行末記号の一覧は「行末記号について」を参照されてください)。

MULTILINE フラグを有効にするには、 compile メソッドの引数に Pattern.MULTILINE を指定してパターンオブジェクトを作成してください。

String r = "^apple";
Pattern p = Pattern.compile(r, Pattern.MULTILINE);

またはパターンを表す文字列の中に埋め込みフラグの (?m) を記述してください。

String r = "(?m)^apple";
Pattern p = Pattern.compile(r);

MULTILINEフラグによるマッチングの違い(キャレット)

MULTILINE フラグを有効にした場合にどのように変わるのかを確認します。最初に行の先頭とマッチするキャレット(^)についてです。パターンとして ^apple を指定した場合で試してみます。

String r = "^apple";
Pattern p = Pattern.compile(r);

デフォルトでは対象の文字列の途中に行末記号があり、文字列が複数の行で構成されていたとしても、キャレット(^)は文字列全体の先頭にのみマッチします。そのため、 apple is red\nlemon is yellow にはマッチしますが、 lemon is yellow\napple is red にはマッチしません。

apple is red\nlemon is yellow
✕ lemon is yellow\napple is red

次に MULTILINE フラグを有効にしてみます。

String r = "^apple";
Pattern p = Pattern.compile(r, Pattern.MULTILINE);

キャレット(^)は文字列全体の先頭に加えて行末記号にもマッチするようになります。

apple is red\nlemon is yellow
〇 lemon is yellow\napple is red
サンプルコード

それでは簡単なサンプルプログラムを作って試してみます。テキストエディタで次のように記述したあと、 JSample18-1.java という名前で保存します。

import java.util.regex.*;

class JSample18_1{
  public static void main(String[] args){
    String target1 = "apple is red\nlemon is yellow";
    String target2 = "lemon is yellow\napple is red";

    String regex = "^apple";
    Pattern p1 = Pattern.compile(regex);

    Matcher m1_1 = p1.matcher(target1);
    System.out.println(target1 + ":" + m1_1.find());
    Matcher m1_2 = p1.matcher(target2);
    System.out.println(target2 + ":" + m1_2.find());

    System.out.println("---- ----");

    Pattern p2 = Pattern.compile(regex, Pattern.MULTILINE);

    Matcher m2_1 = p2.matcher(target1);
    System.out.println(target1 + ":" + m2_1.find());
    Matcher m2_2 = p2.matcher(target2);
    System.out.println(target2 + ":" + m2_2.find());
  }
}

コンパイルを行います。

javac -encoding UTF-8 JSample18_1.java

その後で、次のように実行してください。

java JSample18_1

MULTILINEフラグによるマッチングの違い(キャレット)(1)

MULTILINE フラグを有効にすることで、キャレット(^)が文字列の先頭だけでなく行末記号にもマッチするようになりました。

MULTILINEフラグによるマッチングの違い(ドル記号)

次に行の末尾とマッチするドル記号($)についてです。パターンとして yellow$ を指定した場合で試してみます。

String r = "yellow$";
Pattern p = Pattern.compile(r);

デフォルトでは対象の文字列の途中に行末記号があり、文字列が複数の行で構成されていたとしても、ドル記号($)は文字列全体の末尾にのみマッチします。そのため、 apple is red\nlemon is yellow にはマッチしますが、 lemon is yellow\napple is red にはマッチしません。

〇 apple is red\nlemon is yellow
✕ lemon is yellow\napple is red

次に MULTILINE フラグを有効にしてみます。

String r = "yellow$";
Pattern p = Pattern.compile(r, Pattern.MULTILINE);

ドル記号($)は文字列全体の末尾に加えて行末記号にもマッチするようになります。

〇 apple is red\nlemon is yellow
〇 lemon is yellow\napple is red
サンプルコード

それでは簡単なサンプルプログラムを作って試してみます。テキストエディタで次のように記述したあと、 JSample18-2.java という名前で保存します。

import java.util.regex.*;

class JSample18_2{
  public static void main(String[] args){
    String target1 = "apple is red\nlemon is yellow";
    String target2 = "lemon is yellow\napple is red";

    String regex = "yellow$";
    Pattern p1 = Pattern.compile(regex);

    Matcher m1_1 = p1.matcher(target1);
    System.out.println(target1 + ":" + m1_1.find());
    Matcher m1_2 = p1.matcher(target2);
    System.out.println(target2 + ":" + m1_2.find());

    System.out.println("---- ----");

    Pattern p2 = Pattern.compile(regex, Pattern.MULTILINE);

    Matcher m2_1 = p2.matcher(target1);
    System.out.println(target1 + ":" + m2_1.find());
    Matcher m2_2 = p2.matcher(target2);
    System.out.println(target2 + ":" + m2_2.find());
  }
}

コンパイルを行います。

javac -encoding UTF-8 JSample18_2.java

その後で、次のように実行してください。

java JSample18_2

MULTILINEフラグによるマッチングの違い(ドル記号)(1)

MULTILINE フラグを有効にすることで、ドル記号($)が文字列の末尾だけでなく行末記号にもマッチするようになりました。

-- --

Java の正規表現における MULTILINE フラグの使い方について解説しました。

( Written by Tatsuo Ikura )

Profile
profile_img

著者 / TATSUO IKURA

プログラミングや開発環境構築の解説サイトを運営しています。