4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【正規表現】ちゃんと理解する

4
Posted at

はじめに

正規表現が必要な場面はよくあります。
私は毎回AIに作ってもらって試すのですが、簡単なものは自分でやったほうが早いことに気づきました。
そこで、正規表現をちゃんと理解するために、基本的な内容をまとめます。

正規表現とは

正規表現(Regular Expression、regex)は、文字列のパターンを表現するための記法です。
テキストの検索や置換、バリデーションなど、様々な場面で使われています。

プログラミングでは、以下のような場面で正規表現が活躍します

  • メールアドレスや電話番号の形式チェック
  • ログファイルから特定のパターンを抽出
  • 文字列の一括置換
  • URL のパース(分解)

基本的なメタ文字

正規表現では、特別な意味を持つ文字を「メタ文字」と呼びます。

1. 文字クラス

パターン 説明
. 任意の1文字(改行以外) a.cabc, adc, a1c
\d 数字(0-9) \d\d01, 99
\D 数字以外 \Da, @
\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*cac, abc, abbc
+ 1回以上の繰り返し ab+cabc, abbc
? 0回または1回 ab?cac, 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|dogcat または 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に任せるかもしれません...

参考リンク

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?