Java
 Computer >> コンピューター >  >> プログラミング >> Java

JavaのPattern.UNIX_LINESフィールドとは?実行例でわかりやすく解説

Javaの正規表現API(java.util.regex)には、パターンの挙動を制御するためのさまざまなフラグが用意されています。そのひとつがPattern.UNIX_LINESです。このフラグを有効にすると、正規表現エンジンは「Unixラインモード」で動作し、行末記号として「\n」だけが認識されます。「\r」(キャリッジリターン)は行末記号としては扱われず、通常の文字として処理されます。

UNIX_LINESフラグのポイント

  • 行末記号は「\n」のみ。Windowsの改行(\r\n)や旧Macの改行(\r)は行末として認識されない
  • 「\r」はリテラル文字として扱われるため、メタ文字「.」が「\r」にもマッチできる
  • 「^」や「$」といった行アンカーの解釈も、行末記号が「\n」限定になる

例1:UNIX_LINESフラグを有効にした場合

次のコードでは、行頭が「T」で始まり「e」で終わる文字列にマッチする正規表現「^T.*e」を、UNIX_LINESフラグ付きでコンパイルしています。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UNIX_LINES_Example {
    public static void main(String[] args) {
        String input = "This is the first line\r"
                + "This is the second line\r"
                + "This is the third line\r";

        // 行頭が「T」で始まり「e」で終わる文字列にマッチする正規表現
        String regex = "^T.*e";

        // Patternオブジェクトの生成(UNIX_LINESフラグを指定)
        Pattern pattern = Pattern.compile(regex, Pattern.UNIX_LINES);

        // Matcherオブジェクトの生成
        Matcher matcher = pattern.matcher(input);

        int count = 0;
        while (matcher.find()) {
            count++;
            System.out.println(matcher.group());
        }
        System.out.println("Number of matches: " + count);
    }
}

実行結果

This is the first line
This is the second line
This is the third line
Number of matches: 1

Unixラインモードでは「\r」が通常の文字として扱われるため、メタ文字「.」は「\r」をまたいでマッチできます。その結果、入力全体がひとつの連続した文字列とみなされ、「^T.*e」は最初の「T」から最後の「e」までを一気に取得します。出力は3行に分かれて表示されていますが、これはマッチした文字列内に含まれる「\r」によるもので、実際には1回のマッチで全体を取得している点に注意してください。

例2:フラグなし(通常モード)の場合

同じ正規表現を、UNIX_LINESフラグを付けずにコンパイルするとどうなるか見てみましょう。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UNIX_LINES_Example {
    public static void main(String[] args) {
        String input = "This is the first line\r"
                + "This is the second line\r"
                + "This is the third line\r";

        // 行頭が「T」で始まり「e」で終わる文字列にマッチする正規表現
        String regex = "^T.*e";

        // Patternオブジェクトの生成(フラグなし=通常モード)
        Pattern pattern = Pattern.compile(regex);

        // Matcherオブジェクトの生成
        Matcher matcher = pattern.matcher(input);

        int count = 0;
        while (matcher.find()) {
            count++;
            System.out.println(matcher.group());
        }
        System.out.println("Number of matches: " + count);
    }
}

実行結果

This is the first line
Number of matches: 1

通常モードでは「\r」は行末記号(キャリッジリターン)として扱われます。メタ文字「.」は既定では行末記号にマッチしないため、マッチは最初の行「This is the first line」で止まります。さらに、MULTILINEフラグが無効な場合「^」は入力の先頭にしかマッチしないため、2行目以降がマッチの起点になることはありません。

まとめ

Pattern.UNIX_LINESを使うと、行末記号の解釈が「\n」のみに限定され、両者の動作には次のような違いが生まれます。

  • UNIX_LINES有効時:「\r」は通常文字として扱われ、「.」が「\r」を超えてマッチできる
  • 通常モード:「\r」は行末記号として扱われ、「.」のマッチはその位置で終了する

WindowsのCRLFなど改行コードが混在するテキストを処理する場合や、正規表現の行アンカーの挙動を厳密に制御したいケースでは、UNIX_LINESフラグの影響を理解しておくことが重要です。

  1. JavaのPattern.COMMENTSフィールドとは?使い方を実例付きで解説

    JavaのPatternクラスが持つCOMMENTSフィールドは、正規表現パターンの中に空白文字やコメントを自由に記述できるようにするフラグです。このフラグをcompile()メソッドの第2引数として指定すると、パターン内の空白文字や、#記号で始まるコメント部分はすべて無視されてコンパイルされます。 複雑な正規表現を扱う場合、そのままでは読みにくくなりがちですが、COMMENTSフラグを活用すれば、各部分に説明用のコメントを付けたり、改行やインデントを使って整形したりできるため、可読性と保守性が大きく向上します。なお、このフラグは正規表現内に(?x)を埋め込む方法でも同等の効果が得られます。

  2. 【Java入門】Pattern.CANON_EQフラグの使い方をサンプルコードで解説

    JavaのPatternクラスには、正規表現のマッチング動作を制御するためのさまざまなフラグが用意されています。そのひとつであるCANON_EQフィールドは、「正規化等価(canonical equivalence)」に基づいて文字を照合するためのフラグです。このフラグをcompile()メソッドに指定すると、2つの文字は完全な正準分解(canonical decomposition)の結果が等しい場合に限りマッチするとみなされます。ここでいう正準分解とは、Unicodeのテキスト正規化形式のひとつです。たとえば、アクセント記号付きの合成済み文字(1つのコードポイント)と、基本文字+結合文字(