はじめに
正規表現が必要な場面はよくあります。
私は毎回AIに作ってもらって試すのですが、簡単なものは自分でやったほうが早いことに気づきました。
そこで、正規表現をちゃんと理解するために、基本的な内容をまとめます。
正規表現とは
正規表現(Regular Expression、regex)は、文字列のパターンを表現するための記法です。
テキストの検索や置換、バリデーションなど、様々な場面で使われています。
プログラミングでは、以下のような場面で正規表現が活躍します
- メールアドレスや電話番号の形式チェック
- ログファイルから特定のパターンを抽出
- 文字列の一括置換
- URL のパース(分解)
基本的なメタ文字
正規表現では、特別な意味を持つ文字を「メタ文字」と呼びます。
1. 文字クラス
| パターン | 説明 | 例 |
|---|---|---|
. |
任意の1文字(改行以外) |
a.c → abc, adc, a1c
|
\d |
数字(0-9) |
\d\d → 01, 99
|
\D |
数字以外 |
\D → a, @
|
\w |
単語構成文字(英数字とアンダースコア) |
\w+ → hello, test_123
|
\W |
単語構成文字以外 |
\W → @, !
|
\s |
空白文字(スペース、タブ、改行) |
\s+ → スペース、タブ |
\S |
空白文字以外 | - |
2. 文字クラスの定義
[] を使って、マッチさせたい文字の集合を定義できます。
[abc] # a, b, c のいずれか
[a-z] # a から z までの小文字
[A-Z] # A から Z までの大文字
[0-9] # 0 から 9 までの数字
[a-zA-Z] # すべてのアルファベット
[^abc] # a, b, c 以外(^は否定)
3. 量指定子
| パターン | 説明 | 例 |
|---|---|---|
* |
0回以上の繰り返し |
ab*c → ac, abc, abbc
|
+ |
1回以上の繰り返し |
ab+c → abc, abbc
|
? |
0回または1回 |
ab?c → ac, abc
|
{n} |
ちょうどn回 |
a{3} → aaa
|
{n,} |
n回以上 |
a{2,} → aa, aaa, aaaa
|
{n,m} |
n回以上m回以下 |
a{2,4} → aa, aaa, aaaa
|
4. 位置指定
| パターン | 説明 | 例 |
|---|---|---|
^ |
文字列の先頭 |
^Hello → "Hello world" の Hello |
$ |
文字列の末尾 |
world$ → "Hello world" の world |
\b |
単語の境界 |
\bcat\b → "cat" だが "catch" はマッチしない |
\B |
単語の境界以外 | - |
5. グループ化と選択
| パターン | 説明 | 例 |
|---|---|---|
() |
グループ化(キャプチャ) |
(ab)+ → ab, abab
|
(?:) |
グループ化(非キャプチャ) |
(?:ab)+ → ab, abab
|
| |
OR(選択) |
cat|dog → cat または dog
|
フラグ(オプション)の使い方
正規表現の末尾にフラグを付けることで、マッチングの動作を変更できます。
主要なフラグ一覧
| フラグ | 名称 | 説明 |
|---|---|---|
g |
Global(グローバル) | すべてのマッチを検索(1つ目だけでなく) |
i |
Case-insensitive(大文字小文字無視) | 大文字小文字を区別しない |
m |
Multiline(複数行) |
^ と $ が各行の始まりと終わりにマッチ |
s |
Dotall(ドットオール) |
. が改行文字にもマッチ |
u |
Unicode | Unicode対応の処理を有効化 |
y |
Sticky(固定位置) | lastIndex位置から開始 |
実践的な例
1. メールアドレスのバリデーション
email_validation.js
const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
console.log(emailPattern.test("example@test.com")); // true
console.log(emailPattern.test("invalid.email")); // false
解説:
-
^と$で文字列全体をマッチ -
[a-zA-Z0-9._%+-]+でローカル部分(@の前) -
@でアットマーク -
[a-zA-Z0-9.-]+でドメイン部分 -
\.[a-zA-Z]{2,}でトップレベルドメイン(.com など)
2. 電話番号の抽出
phone_extraction.py
import re
text = "お問い合わせは 03-1234-5678 または 090-9876-5432 まで"
pattern = r'\d{2,4}-\d{4}-\d{4}'
phone_numbers = re.findall(pattern, text)
print(phone_numbers) # ['03-1234-5678', '090-9876-5432']
解説:
-
\d{2,4}で2〜4桁の数字(市外局番) -
-でハイフン -
\d{4}で4桁の数字
3. URLの抽出
url_extraction.js
const text = "Visit https://example.com or http://test.org for more info";
const urlPattern = /https?:\/\/[^\s]+/g;
const urls = text.match(urlPattern);
console.log(urls); // ['https://example.com', 'http://test.org']
解説:
-
https?で http または https(?は sが0回または1回) -
:\/\/でコロンとスラッシュ2つ(エスケープが必要) -
[^\s]+で空白以外の文字が1回以上 -
gフラグで全体検索
4. パスワードの強度チェック
password_validation.py
import re
def is_strong_password(password):
# 8文字以上、大文字・小文字・数字を含む
if len(password) < 8:
return False
has_upper = re.search(r'[A-Z]', password)
has_lower = re.search(r'[a-z]', password)
has_digit = re.search(r'\d', password)
return all([has_upper, has_lower, has_digit])
print(is_strong_password("Pass123")) # False (8文字未満)
print(is_strong_password("Password123")) # True
print(is_strong_password("password123")) # False (大文字なし)
5. 文字列の置換
text_replacement.js
const text = "Today is 2024/01/15. Tomorrow is 2024/01/16.";
// 日付形式を YYYY-MM-DD から YYYY年MM月DD日 に変換
const result = text.replace(
/(\d{4})\/(\d{2})\/(\d{2})/g,
"$1年$2月$3日"
);
console.log(result);
// "Today is 2024年01月15日. Tomorrow is 2024年01月16日."
解説:
-
()でグループ化した部分は$1,$2,$3で参照できる -
gフラグで文字列内のすべてをマッチ
まとめ
慣れない文字が多いので、必要なものだけ覚えていくようにするといいかもしれないです。
私はこれからも複雑なものはAIに任せるかもしれません...
参考リンク