Javaの正規表現を利用した置換、抽出について書きます。
正規表現の基本ルール
パターン | 意味 | 例 | ||
---|---|---|---|---|
パターン | 文字列 | 結果 | ||
^ | 先頭にマッチする | “^ab” | “abcd” “cdab” |
true false |
$ | 末尾にマッチする | “ab$” | “abcd” “cdab” |
false true |
. | 任意の1文字にマッチする | “a.c” | “abc” “abbc” “ac” |
true false false |
? | 直前の文字が0個または1個にマッチする | “^A?$” | “” “A” “AA” “B” |
true true false false |
* | 直前の文字が0個以上にマッチする | “^A*$” | “” “A” “AA” “B” |
true true true false |
+ | 直前の文字が1個以上にマッチする | “^A+$” | “” “A” “AA” “B” |
false true true false |
\d | 半角数値(0~9)にマッチする ※ [0-9]と同じ |
“\\d” | “0123” “0123” “abc” |
true false false |
\D | 半角数値(0~9)以外にマッチする ※ [^0-9]と同じ |
“\\D” | “0123” “0123” “abc” |
false true true |
\w | 半角英数値(0~9、a~z、A~Z、_)にマッチする ※ [0-9a-zA-Z_]と同じ |
“\\w” | “012_AbC” “12Ab” “#$%&” |
true false false |
\W | 半角英数値(0~9、a~z、A~Z、_)以外にマッチする ※ [^0-9a-zA-Z_]と同じ |
“\\W” | “012_AbC” “12Ab” “#$%&” |
false true true |
[ ] | いずれかの文字とマッチする | “[ABC]” | “A” “B” “D” |
true true false |
( ) | 1つのグループとして扱う | “(ABC)” | “ABC” “CBA” |
true false |
{n} | 直前の文字にn回マッチする | “^A{3}$” | “AA” “AAA” “AAAA” |
false true false |
{n,} | 直前の文字にn回以上マッチする | “^A{3,}$” | “AA” “AAA” “AAAA” |
false true true |
{n,m} | 直前の文字にn回以上m回以下マッチする | “^A{3,4}$” | “AA” “AAA” “AAAA” “AAAAA” |
false true true false |
| | いずれかとマッチする | “ABC|DEF” | “ABC” “DEF” “CBA” “DE” |
true true false false |
– | 範囲を指定する | “[3-7]” | “2” “3” “7” “8” |
false true true false |
^ | 否定([ ]の中で使用する) | “[^AB]” | “A” “B” “C” |
false false true |
&& | かつ | “[0-9&&[^4]]” | “3” “4” “5” |
true false true |
Javaでの正規表現の処理の流れ
JavaではPatternクラスとMatchクラスを使って、正規表現を表現します。大まかに下記のような流れです。
Step1 文字列で正規表現を定義
例:郵便番号の場合、数字3桁-4桁なので下記のように表示。※エスケープ文字に注意!
String regex =”\\d{3}-\\d{4}”;
Step2 compileメソッドをつかって、Patternオブジェクトを生成
Patter p = patter.compile( regex );
また改行を含めたい大文字と小文字を含めたいなどは下記のオプションを第2引数にいれればよい。
Patter p = patter.compile( regex , Pattern.CASE_INSENSITIVE );
1 2 3 4 5 6 7 8 |
Pattern.CASE_INSENSITIVE 大文字と小文字を区別しないマッチングを有効にする Pattern.MULTILINE 複数行モードを有効にする Pattern.DOTALL DOTALL モードを有効にする Pattern.UNICODE_CASE Unicode に準拠した大文字と小文字を区別しないマッチングを有効にする Pattern.CANON_EQ 正規等価を有効にする Pattern.UNIX_LINES Unix ラインモードを有効にする Pattern.LITERAL パターンのリテラル構文解析を有効にする Pattern.COMMENTS パターン内で空白とコメントを使用できるようにする |
Step3 Patterオブジェクトのmatcherメソッドを使い、実際の文字列をMatcherオブジェクトにセットする。
Matcher matcher = patter.matcher(“111-1111”);
Step4 Matcherオブジェクトのfindやgroupを使い、判定や抽出を行う
matcher.find()やmatcher.group()など
実処理
判定
対象文字列が正規表現と一致するかを判定する
1 2 3 4 5 6 7 8 9 |
public static void main(String[] args){ String zip1 = "213-9987"; String regex ="\\d{3}-\\d{4}"; Pattern p = Pattern.compile(regex); Matcher m = p.matcher(zip1); if(m.find()){ System.out.print("一致しています。"); } } |
抽出
正規表現に一致するものを抽出する
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public static void main(String[] args){ String regex ="<a href=\"(.*?)\" >"; String href = "<a href=\"http://www.yahoo.co.jp\" >"; Pattern p = Pattern.compile(regex); Matcher m = p.matcher(href); if( m.find()){ System.out.print("group(0)は文字列全体 "+m.group(0)+"\n"); System.out.print("grpuo(1)は1グループ目の一致 "+m.group(1)+"\n"); } } |
置換
正規表現に一致するものを置換する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public static void main(String[] args){ String href = "<a href=\"http://www.yahoo.co.jp\" >ヤフー</a>"; String beforeRegex ="<a href=\"(.*?)\" >(.*?)</a>"; Pattern p = Pattern.compile(beforeRegex); Matcher m = p.matcher(href); //置換後の正規表現 //1つ目のgroupは$1,2つめのgroupは$2 String afterRegex ="href:$1 linkText:$2"; //置換処理 String replacedMessage = m.replaceAll(afterRegex); System.out.print( replacedMessage ); } |