文字列の先頭や末尾などの位置にマッチするパターンを記述する

正規表現では文字列の先頭や末尾、単語の境界など文字そのものではなく位置にマッチするメタ文字が用意されています。例えば文字の先頭とマッチするメタ文字を使用すれば、そのあとに記述したパターンが文字の先頭から始まっている場合だけマッチさせることができます。ここでは Java の正規表現で文字列の先頭や末尾など位置にマッチするパターンの記述方法について解説します。

(Last modified: )

行の先頭にマッチする(^)

メタ文字のひとつであるキャレット(^)は行の先頭位置にマッチします。

^

例えば次のようなパターンは行の先頭から A 、 B 、 C と続く文字列にマッチします。

String regex = "^ABC";

ABC や ABCDEF にはマッチしますが AOC にはマッチしません。ただし行の先頭以外にある場合は ABC であってもマッチしません。

ABCABCDEF
✕ AOC
✕ DEABC

実際にサンプルで試してみます。下記では行の先頭から "Red" という文字列とマッチするかどうかを検索しています。

import java.util.regex.*;

class JSample9_1{
  public static void main(String[] args){
    String regex = "^Red";
    Pattern p = Pattern.compile(regex);

    Matcher m1 = p.matcher("Red Table");
    System.out.println(m1.find());  // true

    Matcher m2 = p.matcher("Reduce speed");
    System.out.println(m2.find());  // true

    Matcher m3 = p.matcher("Border Color is Red");
    System.out.println(m3.find());  // false
  }
}

MULTILINEモード

Java ではキャレット(^)は行の先頭にマッチしますが、文字列に複数の行が含まれていた場合には 2 行目以降の行の先頭にはマッチしません。

String regex = "^ABC";
Pattern p = Pattern.compile(regex);
ABC\nDEF
✕ DEF\nABC

MULTILINE モードを有効にすると各行の先頭でもキャレット(^)がマッチするようになります。

String regex = "^ABC";
Pattern p = Pattern.compile(regex, Pattern.MULTILINE);
ABC\nDEF
〇 DEF\nABC

MULTILINE モードについては別のページにて詳しく解説します。

行の末尾にマッチする($)

メタ文字のひとつであるドル記号($)は行の末尾位置にマッチします。

$

例えば次のようなパターンは ABC という文字列が行の末尾にある場合にマッチします。

String regex = "ABC$";

ABC や DEABC などにマッチしますが AOC にはマッチしません。ただし行の末尾以外にある場合は ABC であってもマッチしません。

ABC
〇 DEABC
✕ AOC
✕ ABCDE

実際にサンプルで試してみます。下記では行の末尾が "Script" で終わる文字列とマッチするかどうか検索しています。

import java.util.regex.*;

class JSample9_2{
  public static void main(String[] args){
    String regex = "Script$";
    Pattern p = Pattern.compile(regex);

    Matcher m1 = p.matcher("JavaScript");
    System.out.println(m1.find());  // true

    Matcher m2 = p.matcher("I am studying TypeScript");
    System.out.println(m2.find());  // true

    Matcher m3 = p.matcher("PostScript is difficult");
    System.out.println(m3.find());  // false
  }
}

MULTILINEモード

Java ではドル記号($)は行の末尾にマッチしますが、文字列に複数の行が含まれていた場合は最後の行以外の行の末尾にはマッチしません。

String regex = "ABC$";
Pattern p = Pattern.compile(regex);
〇 DEF\nABC
✕ ABC\nDEF

MULTILINE モードを有効にすると各行の末尾でもドル記号($)がマッチするようになります。

String regex = "ABC$";
Pattern p = Pattern.compile(regex, Pattern.MULTILINE);
〇 DEF\nABCABC\nDEF

MULTILINE モードについては別のページにて詳しく解説します。

文字列の先頭にマッチする(\A)

メタ文字のひとつである \A は文字列の先頭にマッチします。

\A

メタ文字のキャレット(^)と似ていますが、文字列に複数の行が含まれている場合、 MULTILINE モードを有効にしても文字列全体の先頭にのみマッチします。

例えば次のようなパターンは ABC という文字列が文字列の先頭にある場合にマッチします。

String regex = "\\AABC";

ABC や ABCDE などにマッチしますが AOC にはマッチしません。ただし文字列の先頭以外にある場合は ABC であってもマッチしません。

ABCABCDE
✕ AOC
✕ DEABC

実際にサンプルで試してみます。下記では文字列の先頭から "che" という文字列とマッチするかどうかを検索しています。

import java.util.regex.*;

class JSample9_3{
  public static void main(String[] args){
    String regex = "\\Ache";
    Pattern p = Pattern.compile(regex, Pattern.MULTILINE);

    Matcher m1 = p.matcher("cheese cake");
    System.out.println(m1.find());  // true

    Matcher m2 = p.matcher("check out");
    System.out.println(m2.find());  // true

    Matcher m3 = p.matcher("Apache");
    System.out.println(m3.find());  // false
  }
}

文字列の末尾にマッチする(\z,\Z)

メタ文字のひとつである \z および \Z は文字列の末尾にマッチします。

\z
\Z

メタ文字のドル記号($)と似ていますが、文字列に複数の行が含まれている場合、 MULTILINE モードを有効にしても文字列全体の末尾にのみマッチします。

例えば次のようなパターンは ABC という文字列が文字列の先頭にある場合にマッチします。

String regex = "ABC\\z";

ABC や DEABC などにマッチしますが AOC にはマッチしません。ただし文字列の末尾にあるとき以外は ABC であってもマッチしません。

ABC
〇 DEABC
✕ AOC
✕ ABCDE

\z と \Z は基本的に同じ使い方をしますが、文字列の末尾が行末記号だった場合に異なります。詳しくはこのあとで解説します。

実際にサンプルで試してみます。下記では文字列の先頭から "che" という文字列とマッチするかどうかを検索しています。

import java.util.regex.*;

class JSample9_4{
  public static void main(String[] args){
    String regex = "che\\z";
    Pattern p = Pattern.compile(regex);

    Matcher m1 = p.matcher("cheese cake");
    System.out.println(m1.find());  // false

    Matcher m2 = p.matcher("page cache");
    System.out.println(m2.find());  // true

    Matcher m3 = p.matcher("Apache");
    System.out.println(m3.find());  // true
  }
}

\zと\Zの違いについて

メタ文字の \z と \Z はどちらも文字列の末尾とマッチしますが、 \Z の場合は対象の文字列の末尾が行末文字だった場合に行末文字を取り除いた状態でマッチするかどうかを検索します。

例えば対象の文字列が "ABC\n" のように文字列の末尾に行末文字の一つである "\n" だった場合、パターン "ABC\z" はマッチしませんが、パターン "ABC\Z" はマッチします。

実際にサンプルで試してみます。どちらも文字列の最後に行末文字がない場合は同じ結果となりますが、文字列の最後に行末文字がある場合は結果が異なります。

import java.util.regex.*;

class JSample9_5{
  public static void main(String[] args){
    // \z の場合
    String regex1 = "ABC\\z";
    Pattern p1 = Pattern.compile(regex1);

    Matcher m1 = p1.matcher("ABC");
    System.out.println(m1.find());  // true

    Matcher m2 = p1.matcher("ABC\n");
    System.out.println(m2.find());  // false

    // \Z の場合
    String regex2 = "ABC\\Z";
    Pattern p2 = Pattern.compile(regex2);

    Matcher m3 = p2.matcher("ABC");
    System.out.println(m3.find());  // true

    Matcher m4 = p2.matcher("ABC\n");
    System.out.println(m4.find());  // true
  }
}

単語境界にマッチする(\b)

メタ文字のひとつである \b は単語境界にマッチします。

\b

単語境界というのは、単語を構成する文字( a-z 、 A-Z 、 0-9 、 _ 、 Unicode 文字)とそうでない文字との境目のことです。次の図を見て下さい。

単語境界にマッチする(1)

対象の文字列が "How much?" の場合、単語境界は 4 つあります。

(1) 行頭と "H" の間
(2) "w" と空白文字の間
(3) 空白文字と "m" の間
(4) "h" と "?" の間 

例えば次のようなパターンは work という文字列が単語境界のあとにある場合にマッチします。

String regex = "\\bwork";

"work" や "next working" などにマッチしますが "fireworks" にはマッチしません。

work
〇 next working
✕ fireworks

例えば次のようなパターンは ing という文字列のあとに単語境界がある場合にマッチします。

String regex = "ing\\b";

"swimming" や "next working" などにマッチしますが "ingenious" にはマッチしません。

〇 swimming
〇 next working
✕ ingenious

\b を単語の先頭と末尾にそれぞれ使用した次のようなパターンは working という単語の場合だけにマッチします。前後に文字が付いている場合はマッチしません。

String regex = "\\bworking\\b";

実際にサンプルで試してみます。

import java.util.regex.*;

class JSample9_6{
  public static void main(String[] args){
    String regex1 = "\\bwork";
    Pattern p1 = Pattern.compile(regex1);

    Matcher m1 = p1.matcher("a working person");
    System.out.println(m1.find());  // true

    Matcher m2 = p1.matcher("Go to see fireworks");
    System.out.println(m2.find());  // false

    String regex2 = "ing\\b";
    Pattern p2 = Pattern.compile(regex2);

    Matcher m3 = p2.matcher("a working person");
    System.out.println(m3.find());  // true

    Matcher m4 = p2.matcher("ingenious design");
    System.out.println(m4.find());  // false
  }
}

非単語境界にマッチする(\B)

メタ文字のひとつである \B は非単語境界にマッチします。

\B

非単語境界というのは、単語境界以外の境目のことです次の図を見て下さい。

非単語境界にマッチする(1)

対象の文字列が "How much?" の場合、単語境界は 6 つあります。

(1) "H" と "o" の間 
(2) "o" と "w" の間 
(3) "m" と "u" の間 
(4) "u" と "c" の間 
(5) "c" と "h" の間 
(6) "?" と行末の間 

例えば次のようなパターンは am という文字列が非単語境界のあとにある場合にマッチします。

String regex = "\\Bam";

"sample" や "program" などにマッチしますが "amount" にはマッチしません。

〇 sample
〇 program
✕ amount

例えば次のようなパターンは am という文字列のあとに非単語境界が続く場合にマッチします。

String regex = "am\\B";

"sample" や "amount" などにマッチしますが "program" にはマッチしません。

〇 sample
〇 amount
✕ program

実際にサンプルで試してみます。

import java.util.regex.*;

class JSample9_7{
  public static void main(String[] args){
    String regex1 = "\\Bam";
    Pattern p1 = Pattern.compile(regex1);

    Matcher m1 = p1.matcher("Difficult program");
    System.out.println(m1.find());  // true

    Matcher m2 = p1.matcher("Go to see fireworks");
    System.out.println(m2.find());  // false

    String regex2 = "am\\B";
    Pattern p2 = Pattern.compile(regex2);

    Matcher m3 = p2.matcher("Difficult program");
    System.out.println(m3.find());  // false

    Matcher m4 = p2.matcher("full amount");
    System.out.println(m4.find());  // true
  }
}

-- --

Java の正規表現で文字列の先頭や末尾など位置にマッチするパターンの記述方法について解説しました。

( Written by Tatsuo Ikura )

Profile
profile_img

著者 / TATSUO IKURA

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