文字クラスの集合演算

広告

Javaの文字クラスでは集合演算を行うことができます。

まずはORです。書式は次の通りです。

"[a-c[f-h]]"
"[[a-c]f-h]"
"[[a-c][f-h]]"

上記は全て同じで"[a-cf-h]"と単に記載した場合と同じです。つまり「a~c」と「f~h」のいずれの文字に一致する文字列にマッチします。このように文字クラスの中に他の文字クラスを記載するとORのように働きます。あえてこのような記載の仕方をする意味は今のところ思いつきません。

次はANDです。書式は次の通りです。

"[a-c&&[cde]]"
"[a-c&&[c-e]]"
"[[a-c]&&[c-e]]"

上記は「a~c」且つ「c~e」となります。つまりこの場合は"[c]"と書いた場合と同じです。このように文字クラスの中で他の文字クラスとメタ文字の"&&"を使ってつなげるとANDのように働きます。

ANDの便利な点は次のような記述が行えることです。

"[a-z&&[^f-m]]"

上記は「a~z」且つ「f~m以外」となります。つまり「a~z」の中で「f~m」の部分を除いたものになります。このように否定の文字クラスとのANDを取ることで、あたかも差分を取ったような文字クラスを定義することができます。

具体的には次のように記述します。

String str = "Document No.7";
String regex = "No.[0-9&&[^2-4]";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);

if (m.find()){
  System.out.println("マッチしました");
}else{
  System.out.println("マッチしません");
}

上記の場合はマッチします。

サンプルプログラム

では実際に試してみます。

JSample4_1.java

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

class JSample4_1{
  public static void main(String args[]){
    String str1 = "bbb";
    String str2 = "ggg";
    String str3 = "nnn";

    String regex1 = "[[a-d][x-z]]";
    Pattern p1 = Pattern.compile(regex1);

    String regex2 = "[[a-m]&&[d-z]]";
    Pattern p2 = Pattern.compile(regex2);

    String regex3 = "[[a-z]&&[^f-m]]";
    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()){
      System.out.println("○ " + target);
    }else{
      System.out.println("× " + target);
    }
  }
}

ではコンパイルを行った上で実行してみます。

p4-1

( Written by Tatsuo Ikura )