Java 正規表現
今回はポンコツ2人組が正規表現に挑戦します! 正規表現はパターンの指定が複雑で初心者にはなかなか敷居が高いですよね。 ですが覚えておくと非常に役に立つので頑張って覚えましょう!
今回は以下の10パターンに挑戦しました。
① 文字列が特定のパターンに一致するか
② 文字列内のすべての一致を取得する
③ 文字列内のパターンを置換する
④ 正規表現を使用して文字列を分割する
⑤ 文字列内の数字を取得する
⑥ 文字列中の10文字目と11文字目が"20"かを判定
⑦ 正規表現であいまい検索
⑧ 正規表現で半角英数字のみを含むかを判定
⑨ 正規表現で全角文字が含まれているか判定
⑩ 数値のみ(マイナス記号と小数点を含む)の判定
package regexSample;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Sample {
public static void main(String[] args) {
//-----------------------------------------------------------
// ① 文字列が特定のパターンに一致するかどうかを確認する
//-----------------------------------------------------------
String input = "ポンコツ女子はとても可愛らしい人です";
String pattern = "女子";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(input);
if (m.find()) {
System.out.println("① 一致しました");
} else {
System.out.println("① 一致しませんでした");
}
System.out.println("");
//-----------------------------------------------------------
// ② 文字列内のすべての一致を取得する
//-----------------------------------------------------------
String input2 = "I'm a ponkotsu boy. thank you always";
String pattern2 = "\\b\\w{5}\\b"; // 5文字の単語
Pattern p2 = Pattern.compile(pattern2);
Matcher m2 = p2.matcher(input2);
while (m2.find()) {
System.out.println("② 一致: " + m2.group());
}
System.out.println("");
//-----------------------------------------------------------
// ③ 文字列内のパターンを置換する
//-----------------------------------------------------------
String input3 = "私はポンコツ男子。ただいまミッション進行中だ。";
String pattern3 = "\\男子\\b";
String replaced = input3.replaceAll(pattern3, "女子");
System.out.println("③ 置換: " + replaced);
System.out.println("");
//-----------------------------------------------------------
// ④ 正規表現を使用して文字列を分割する
//-----------------------------------------------------------
String input4 = "喜,怒,哀,楽";
String[] kidoairaku = input4.split(",");
for (String kanjyo : kidoairaku) {
System.out.println("④ 感情: " + kanjyo);
}
System.out.println("");
//-----------------------------------------------------------
// ⑤ 文字列内の数字を取得する
//-----------------------------------------------------------
String input5 = "鎌倉幕府が成立した年号は1192年?もしくは1185年?";
Pattern p5 = Pattern.compile("\\d+");
Matcher m5 = p5.matcher(input5);
while (m5.find()) {
System.out.println("⑤ 数字: " + m5.group());
}
System.out.println("");
//-----------------------------------------------------------
// ⑥ 文字列中の10文字目と11文字目が"20"かを正規表現で判定
//-----------------------------------------------------------
String input6 = "ABC345DEF20GHI4567JKL";
// 10文字目と11文字目が"20"かを判定する正規表現パターン
String pattern6 = "^.{9}20";
Pattern p6 = Pattern.compile(pattern6);
Matcher m6 = p6.matcher(input6);
if (m6.find()) {
System.out.println("⑥ 10文字目と11文字目は\"20\"です。");
} else {
System.out.println("⑥ 10文字目と11文字目は\"20\"ではありません。");
}
System.out.println("");
//-----------------------------------------------------------
// ⑦ 正規表現であいまい検索
//-----------------------------------------------------------
String input7 = "私のパソコンは古いので非常に重たいのです";
// 「パソコンは」と「重たい」の間にある任意の文字列
String pattern7 = "パソコンは.*重たい";
Pattern p7 = Pattern.compile(pattern7);
Matcher m7 = p7.matcher(input7);
if (m7.find()) {
System.out.println("⑦ ヒットしました");
} else {
System.out.println("⑦ ヒットしませんでした");
}
System.out.println("");
//-----------------------------------------------------------
// ⑧ 正規表現で半角英数字のみを含むかを判定
//-----------------------------------------------------------
String input8 = "AbCdEfG1234567890";
// 半角英数字のみを含むかを判定する正規表現パターン
String pattern8 = "^[a-zA-Z0-9]+$";
Pattern p8 = Pattern.compile(pattern8);
Matcher m8 = p8.matcher(input8);
if (m8.find()) {
System.out.println("⑧ 半角英数字のみです");
} else {
System.out.println("⑧ 半角英数字以外が含まれています");
}
System.out.println("");
//-----------------------------------------------------------
// ⑨ 正規表現で全角文字が含まれているか判定
//-----------------------------------------------------------
String input9 = "ABcdeFGHあIJKLMN";
// 全角文字が含まれているかを判定する正規表現パターン
String pattern9 = "[^\\x01-\\x7E]"; // 0x01-0x7Eまでが半角文字の範囲
Pattern p9 = Pattern.compile(pattern9);
Matcher m9 = p9.matcher(input9);
if (m9.find()) {
System.out.println("⑨ 全角文字が含まれています");
} else {
System.out.println("⑨ 全角文字は含まれていません");
}
System.out.println("");
//-----------------------------------------------------------
// ⑩ 数値のみ(マイナス記号と小数点を含む)の判定
//-----------------------------------------------------------
String input10 = "-123.45";
// マイナス記号と小数点を含む数値のみを判定する正規表現パターン
String pattern10 = "^-?\\d*\\.?\\d+$";
Pattern p10 = Pattern.compile(pattern10);
Matcher m10 = p10.matcher(input10);
if (m10.find()) {
System.out.println("⑩ 数値です");
} else {
System.out.println("⑩ 数値ではありません");
}
System.out.println("");
}
}
処理結果は次の通りです。
① 一致しました
② 一致: thank
③ 置換: 私はポンコツ女子。ただいまミッション進行中だ。
④ 感情: 喜
④ 感情: 怒
④ 感情: 哀
④ 感情: 楽
⑤ 数字: 1192
⑤ 数字: 1185
⑥ 10文字目と11文字目は"20"です。
⑦ ヒットしました
⑧ 半角英数字のみです
⑨ 全角文字が含まれています
⑩ 数値です
これらはJavaで正規表現を使用する際の基本的な操作です。
②の"\b\w{5}\b"は5文字の単語にマッチするパターンです。
・"\b" : ワードの境界を示す特殊文字です。
・"\w" : 単語文字を示す特殊文字です。アルファベット、数字、アンダースコア(_)にマッチします。
・"{5}" : 直前のパターン(ここでは "\w")が5回繰り返されることを示します。
・"\b" : ワードの境界を示す特殊文字です。
③の"\男子\b"は"男子"という文字列の後にワードの境界がある場合にマッチします。
例えば、"男子"という単語の後に空白や句読点などがある場合にマッチしますが、"男子"という文字列が一部の大文字や数字と続く場合にはマッチしません。
⑤の"\d+"は1つ以上の数字にマッチします。
・"\d": 数字を示す特殊文字です。[0-9]と同じ意味を持ちます。
・"+": 直前のパターン(ここでは "\d")が1回以上繰り返されることを示します。
⑥では、文字列の先頭から9文字目までの任意の文字に続いて"20"が来るかどうかを確認する正規表現パターンを使用しています。これにより、文字列の10文字目と11文字目が"20"であるかどうかを判定できます。
⑦では、"パソコンは"と"重たい"の間にある任意の文字列を含む部分文字列を検索しています。
⑧では、^[a-zA-Z0-9]+$という正規表現パターンを使用しています。
・"^": 行の先頭を示します。
・"[a-zA-Z0-9]": アルファベット(大文字と小文字)と数字を示します。
・"+": 直前の文字セット([a-zA-Z0-9])が1回以上繰り返されることを示します。
・"$": 行の末尾を示します。
⑨では、正規表現パターン[^\\x01-\\x7E]を使用しています。このパターンは、文字列内で0x01から0x7EまでのASCII範囲以外の文字(つまり、全角文字)を検索します。
・"^": 否定を示すメタ文字で、パターンの先頭に置かれることで、指定された範囲以外の文字をマッチングします。
・"\\x01-\\x7E": ASCII範囲(0x01から0x7Eまで)を示します。
⑩では、正規表現パターン^-?\\d*\\.?\\d+$を使用しています。このパターンは、マイナス記号(-)、整数部分、小数点(.)、小数部分を含む数値のみを検索します。
・"^": 行の先頭を示します。
・"-?": マイナス記号(-)が0回または1回現れることを示します。
・"\\d*": 数字(0から9までのいずれか)が0回以上繰り返されることを示します。
・"\\.?": 小数点(.)が0回または1回現れることを示します。
・"\\d+": 小数部分に数字が1回以上繰り返されることを示します。
・"$": 行の末尾を示します。
ここまで正規表現の書き方について解説してきましたが理解できましたか?
こうしてみると難しいですね・・・これは覚えられなくても仕方がないかも知れません。 ですが、せめて何ができるのかだけでも頑張って覚えましょう!