【Java】正規表現 [4] 文字列の抽出 ~Matcher.group() ~

■ 基本編

 * パターンの中で、マッチした部分を取り出したい部分を括弧()で囲う

構文

# 1, 2, ...
String result1 = matcher.group(1);
String result2 = matcher.group(2);
...

参考文献

http://www.javadrive.jp/regex/ref/index2.html

サンプル

■ 例1 : 正規表現で文字列抽出

 * 「【任意文字】Version【空白】:【空白】XXXXX【空白】」のフォーマットで
    "XXXXX"部分を抽出する
Main.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

  public static void main(String[] args) {
    Pattern pattern = Pattern.compile("^.*Version[ \\t]*:[ \\t]*(.*)[ \\t]*$");
    Matcher matcher = pattern.matcher(" Version : 1.0.1");
    if (matcher.matches()) {
      System.out.println("Result : " + matcher.group(1));
    }
  }
}
出力結果
Result : 1.0.1

■ 例2 : コード内の要素分割

 * コード「【文字(A-Z)】【数字(2桁)】【文字(A-Z)】【数字(連番)】」のフォーマットで
    各要素を分割し、抽出する。
CodeSplitter.java
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CodeSplitter {

  public static void main(String[] args) {
    // Ex1
    System.out.println("**********************");
    try {
      String input1 = "A19A0001";
      List<String> results1 = split(input1);
      for (String result : results1) {
        System.out.println("Rsult1 : " + result);
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }

    // Ex2
    System.out.println("**********************");
    try {
      String input2 = "BB16ZZ0002";
      List<String> results2 = split(input2);
      for (String result : results2) {
        System.out.println("Rsult2 : " + result);
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    
    // Ex3:2要素目が3桁(エラー)
    System.out.println("**********************");
    try {
      String input3 = "BB161ZZ0002";
      List<String> results3 = split(input3);
      for (String result : results3) {
        System.out.println("Rsult3 : " + result);
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  private static List<String> split(String targetCode) throws Exception {
    Pattern pattern = Pattern.compile("^([A-Z]+)([0-9]{2})([A-Z]+)([0-9]+)$");
    Matcher matcher = pattern.matcher(targetCode);
    if (!matcher.matches() || matcher.groupCount() != 4) {
      throw new Exception("Not Supported Code");
    }
    return Arrays.asList(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4));
  }
}

出力結果
**********************
Rsult1 : A
Rsult1 : 19
Rsult1 : A
Rsult1 : 0001
**********************
Rsult2 : BB
Rsult2 : 16
Rsult2 : ZZ
Rsult2 : 0002
**********************
java.lang.Exception: Not Supported Code
	at com.sample.regularex.CodeSplitter.split(CodeSplitter.java:52)
	at com.sample.regularex.CodeSplitter.main(CodeSplitter.java:39)

■ 例3 : 「key=Value # Comment」形式

プロパティ・ファイル(.properties) の「key=Value(# Comment)」形式を
保存する際に、Javaのデフォルトの標準ライブラリを使うと
http://blogs.yahoo.co.jp/dk521123/32137862.html
の注意書きに書いた通り、「コメントアウト(#)がなくなってまう」などの
問題があるので、自作しようかなーっと思って、その第一段階として
正規表現を使って「key=Value # Comment」形式を検索・パースできるソースを作ってみる
SampleRegularExpression.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SampleRegularExpression {

   public static void main(String[] args) {
      show("key1", "key1=value1 # comment1");
      show("sample.key2", " sample.key2 = value2 # comment2 ");
      show("sample.key3", " 	sample.key3	 =	 value3-1.value3-2	 # 	comment3	  ");
   }

   private static void show(String key, String target) {
      String pattern = String.format(
            "[ \\t]*(%s)[ \\t]*=[ \\t]*(.+)[ \\t]*#[ \\t]*(.+)[ \\t]*$",
            key.replace("\\.", "\\\\."));
      Matcher matcher = Pattern.compile(pattern).matcher(target);
      while(matcher.find()) {
          System.out.println(matcher.group(1));
          System.out.println(matcher.group(2));
          System.out.println(matcher.group(3));
      }
   }
}
出力結果
key1
value1 
comment1
sample.key2
value2 
comment2 
sample.key3
value3-1.value3-2	 
comment3	  

# * 余分な空白は含まれるがとりあえずは。。。本当はコメントがある時とない時でも問題なく動作させたいが。。。
参考文献
http://d.hatena.ne.jp/mtoyoshi/20081005/1223186868
http://javamemo.jpn.org/index.php?%5B%5B%C0%B5%B5%AC%C9%BD%B8%BD%5D%5D#content_1_11
http://d.hatena.ne.jp/mmasashi/20091030/1256919089

関連記事

正規表現 [1] 一致・不一致の判定 ~Matcher.matches() ~

http://blogs.yahoo.co.jp/dk521123/33605882.html

正規表現 [2] 複雑な文字列置き換え ~ replaceFirst / replaceAll ~

http://blogs.yahoo.co.jp/dk521123/34781790.html

正規表現 [3] 数字/文字の出現回数を数える ~Matcher.find() ~

http://blogs.yahoo.co.jp/dk521123/36448306.html

正規表現について

http://blogs.yahoo.co.jp/dk521123/26123295.html

Javaの文字列の扱い ~ String ~

http://blogs.yahoo.co.jp/dk521123/13687446.html