正規表現の基本
- 文字クラス:
[abc]
:a
,b
,c
のいずれかにマッチ[^abc]
:a
,b
,c
以外の文字にマッチ[a-z]
:a
からz
の範囲内の文字にマッチ
- 特殊文字:
\d
: 数字(0-9
)にマッチ\D
: 数字以外にマッチ\w
: 英数字またはアンダースコアにマッチ([a-zA-Z_0-9]
)\W
: 英数字またはアンダースコア以外にマッチ\s
: 空白文字(スペース、タブなど)にマッチ\S
: 空白文字以外にマッチ
- 量指定子:
*
: 0回以上の繰り返し+
: 1回以上の繰り返し?
: 0回または1回{n}
: 正確に n 回の繰り返し{n,}
: n 回以上の繰り返し{n,m}
: n 回以上、m 回以下の繰り返し
初心者歓迎!手と目で覚える正規表現入門・その1「さまざまな形式の電話番号を検索しよう」
https://qiita.com/jnchito/items/893c887fbf19e17d3ff9
Javaでの利用
文字列の完全一致判定
import java.util.*;
public class Reapp{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.print("郵便番号を入力>>");
String code = sc.next();
String regex= "\\d{3}-?\\d{4}";
if(code.matches(regex)){
System.out.println("ok");
}else{
System.out.println("ng");
}
}
}
ポイント解説
● 文字列.matches(パターン)を使って完全一致を検索できる。戻り値はboolean
部分一致判定
文字列に含まれるかどうかを判定するには
java.util.regex.Pattern
java.util.regex.Matcher
クラスを使う。
import java.util.regex.*;
public class Reapp{
public static void main(String[] args){
String s = "りんご:100円,ばなな:50円";
//Patternインスタンスを作成
Pattern pattern=Pattern.compile("\\d+");
//Matcherインスタンスを作成
Matcher matcher=pattern.matcher(s);
//find()は最初の一致を探し、見つかった場合はその位置を記録
while(matcher.find()){
//マッチした部分を表示
System.out.println(matcher.group());
}
}
}
[実行結果]
100
50
ポイント
●import java.util.regex.*; としてPatternクラスやMatcherクラスを短い名前で使えるようにする。
●matcher.find()で見つかったマッチ部分の終了位置に移動する
●matcher.group()で見つかったマッチ部分を取得する
置換
文字列.replaceAll(パターン,置換後)
を使うことで置換した文字列を作成することができる
public class Reapp{
public static void main(String[] args){
String s = "りんご:100円,ばなな::50円";
String result=s.replaceAll("::?","->");
System.out.println(result);
}
}
[実行結果]
りんご->100円,ばなな->50円
キャプチャを使っての置換
replaceAllはキャプチャを使っての置換もできる
public class Reapp{
public static void main(String[] args){
String s = "りんご:100円,ばなな:50円";
String result=s.replaceAll("(\\d+)円","¥$1");
System.out.println(result);
}
}
マッチ部分に複雑な処理を入れて置換する
金額部分を2倍にした文字列を作成してみよう。
import java.util.regex.*;
public class Reapp{
public static void main(String[] args){
String s = "りんご:100円,ばなな:50円";
//正規表現で[数字+円]の数字部分をキャプチャ
Pattern pattern=Pattern.compile("(\\d+)円");
Matcher matcher=pattern.matcher(s);
//StringBufferに結果を蓄積
StringBuffer result=new StringBuffer();
//価格を2倍にして置換
while(matcher.find()){
int price = Integer.parseInt(matcher.group(1)) * 2;
matcher.appendReplacement(result,price+"円");
}
matcher.appendTail(result);
//結果を表示
System.out.println(result.toString());
}
}
[実行結果]
りんご:200円,ばなな:100円
解説
Pattern.compile("(\\d+)円")
:\\d+
: 1つ以上の数字にマッチします。円
: 文字列「円」にマッチします。- 全体として、数字の部分と「円」の部分をキャプチャします。
matcher.find()
:- マッチする部分を順番に見つけて処理します。
matcher.group(1)
:- キャプチャグループ
(\\d+)
で取得した数字部分を取り出し、それを整数に変換します。
- キャプチャグループ
matcher.appendReplacement(result, price + "円")
:- 価格を2倍にして
"円"
を付けて置換します。
- 価格を2倍にして
matcher.appendTail(result)
:- マッチしなかった部分を結果に追加します。
英単語、正規表現検索
以下のくじらはんどさんのリンクからejdict-hand-utf8.zipをダウンロード&解凍をして、プロジェクト配下にejdict-hand-utf-8.txtを配置する
無料 英和辞書データ ダウンロード - ブラウザで使えるWeb便利ツール
ブラウザ上で手軽に使える便利ツール
Reapp.javaを以下のように作成する
import java.util.*;
import java.util.regex.*;
import java.io.*;
public class Reapp {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
System.out.print("正規表現を入力[q]で終了>>");
String regStr = sc.nextLine();
if (regStr.isEmpty()) continue;
if (regStr.equals("q")) break;
Pattern pattern;
try {
pattern = Pattern.compile(regStr);
} catch (PatternSyntaxException e) {
System.out.println("無効な正規表現です。");
continue;
}
try (FileInputStream fis = new FileInputStream("./ejdict-hand-utf8.txt");
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr)) {
int cnt = 0;
String line;
while ((line = br.readLine()) != null) {
String word = line.split("\t")[0]; // タブで分割し、単語のみ取得
Matcher matcher = pattern.matcher(word);
if (matcher.matches()) {
System.out.println(word);
cnt++;
if (cnt >= 20) break; // カウント上限に達したら終了
}
}
} catch (IOException e) {
System.out.println("ファイル読み込み中にエラーが発生しました: " + e.getMessage());
}
}
sc.close();
}
}
コメント