正規表現マスターへの道!主要6言語で学ぶ、パターンマッチングの基礎

正規表現とは

正規表現(Regular Expression、略称:regex)とは、特定のパターンを表すための文字列の記法。これは、テキスト内の特定の文字列を検索したり、置換したり、抽出したりするために広く使われる。

正規表現の使用法

  • 文字列の検索
  • 文字列の置換
  • 文字列の分割

正規表現20選

よく使われる正規表現の一覧です。

正規表現 説明 例(Javascript)
. 任意の1文字を表す。 'a.c'.match(/a.c/) // ['abc']
* 直前の文字が0回以上繰り返されることを表す。 'aaabc'.match(/a*/) // ['aaa']
+ 直前の文字が1回以上繰り返されることを表す。 'aaabc'.match(/a+/) // ['aaa']
? 直前の文字が0回または1回出現することを表す。 'ac'.match(/a?b?c/) // ['ac']
{n} 直前の文字がn回繰り返されることを表す。 'aaabc'.match(/a{3}/) // ['aaa']
{n,m} 直前の文字がn回以上m回以下繰り返されることを表す。 'aaabc'.match(/a{2,3}/) // ['aaa']
^ 行の開始を表す。 'abc'.match(/^a/) // ['a']
$ 行の終了を表す。 'abc'.match(/c$/) // ['c']
\b 単語の境界を表す。 'abc abc'.match(/\babc\b/) // ['abc']
\B 単語の非境界を表す。 'abcabc'.match(/\Babc\B/) // null
\d 数字を表す。 '123'.match(/\d{3}/) // ['123']
\D 非数字を表す。 'abc'.match(/\D{3}/) // ['abc']
\w 単語文字を表す。 'abc_123'.match(/\w{7}/) // ['abc_123']
\W 非単語文字を表す。 '@#$%'.match(/\W{4}/) // ['@#$%']
\s 空白文字を表す。 ' '.match(/\s{3}/) // [' ']
\S 非空白文字を表す。 'abc'.match(/\S{3}/) // ['abc']
[abc] abcのいずれか1文字を表す。 'abc'.match(/[abc]{3}/) // ['abc']
[^abc] abcを除く任意の1文字を表す。 'def'.match(/[^abc]{3}/) // ['def']
(abc) グループ化されたabcを表す。 'abcabc'.match(/(abc){2}/) // ['abcabc']
` ` aまたはbを表す。

作成方法

各プログラミング言語の正規表現の作成方法と、それぞれの正規表現の例を表です。

言語 正規表現の作成方法 正規表現の例
JavaScript スラッシュで囲む。オプションフラグをスラッシュの後に付けられる。 /abc/g
Python reモジュールを使用し、Raw文字列記法(rを先頭に)で表現する。 re.compile(r"abc")
Java java.util.regexパッケージを使用し、正規表現をコンパイルするかしないか選べる。コンパイル時にオプションフラグを付けられる。 Pattern.compile("abc", Pattern.CASE_INSENSITIVE)
Ruby スラッシュで囲む(他の作成方法もあり)。オプションフラグをスラッシュの後に付けられる。 /abc/i
Go regexpパッケージを使用し、バッククォーテーションで囲んでコンパイルする。正規表現の先頭にオプションフラグを付けられる。 regexp.Compile(abc)
PHP preg_系の関数を使用して表現する。パターンはスラッシュやハッシュなどで囲む。オプションフラグを最後のデリミタの後に付けられる。 preg_match('/abc/i', $subject)

各言語で正規表現を作成する方法とそれぞれの具体的な例を一覧で確認することができます。それぞれの言語での正規表現の詳細や特性については、各言語の公式ドキュメンテーションをご参照ください。

文字列チェック

JavaScript、Python、Java、Ruby、Go、PHPの正規表現による文字列チェックの方法とそれぞれの例の表です。

言語 正規表現による文字列チェック
JavaScript test:マッチするか真偽値で返す。
search:最初にマッチした文字列の位置を返す。
match:マッチした文字列を配列で返す。
/abc/.test("abcdef")
"abcdef".search(/abc/)
"abcdef".match(/abc/)
Python match:先頭からマッチするとマッチオブジェクトを返す。
search:マッチするとマッチオブジェクトを返す。
fullmatch:全体がマッチするとマッチオブジェクトを返す。
findall:マッチした文字列をリストで返す。
re.match(r"abc", "abcdef")
re.search(r"abc", "abcdef")
re.fullmatch(r"abc", "abcdef")
re.findall(r"abc", "abcdef")
Java matches:マッチするか真偽値で返す。
find:マッチした部分シーケンスを返す。
Pattern.matches("abc", "abcdef")
Pattern.compile("abc").matcher("abcdef").find()
Ruby match?:マッチするか真偽値で返す。
match:マッチするとMatchDataオブジェクトを返す。
=~:マッチした文字列の位置を返す。
/abc/.match?("abcdef")
/abc/.match("abcdef")
/abc/ =~ "abcdef"
Go MatchString:マッチするか真偽値で返す。
FindString:最初にマッチした文字列を返す。
FindStringIndex:最初にマッチした文字列の位置を配列で返す。
FindAllString:マッチした文字列を配列で返す。
regexp.MatchString(abc, "abcdef")
regexp.MustCompile(abc).FindString("abcdef")
regexp.MustCompile(abc).FindStringIndex("abcdef")
regexp.MustCompile(abc).FindAllString("abcdef", -1)
PHP preg_match:マッチするか真偽値で返す。
preg_match_all:マッチした文字列を配列で返す。
preg_match('/abc/', "abcdef")
preg_match_all('/abc/', "abcdef", $matches)

文字列置換

言語 正規表現による文字列置換
JavaScript replace:一部または全体を置換する。 "abcdef".replace(/abc/, "xyz")
Python sub:全てのマッチする文字列を置換する。置換回数を指定できる。 re.sub(r"abc", "xyz", "abcdef")
Java replaceAll:全てのマッチする文字列を置換する。
replaceFirst:最初のマッチする文字列を置換する。
Pattern.compile("abc").matcher("abcdef").replaceAll("xyz")
Pattern.compile("abc").matcher("abcdef").replaceFirst("xyz")
Ruby gsub:全てのマッチする文字列を置換する。
sub:最初のマッチする文字列を置換する。
"abcdef".gsub(/abc/, "xyz")
"abcdef".sub(/abc/, "xyz")
Go ReplaceAllString:全てのマッチする文字列を置換する。 regexp.MustCompile(abc).ReplaceAllString("abcdef", "xyz")
PHP preg_replace:全てのマッチする文字列を置換する。 preg_replace('/abc/', "xyz", "abcdef")

文字列抽出

JavaScript、Python、Java、Ruby、Go、PHPの正規表現による文字列抽出の方法とそれぞれの例の表です。

言語 正規表現による文字列抽出
JavaScript 括弧()で指定したパターンを抽出。抽出したパターンは$1$2で参照。 "abcdef".match(/(abc)(def)/)
Python 括弧()で指定したパターンを抽出。抽出したパターンは\1\2で参照。 re.search(r"(abc)(def)", "abcdef").groups()
Java 括弧()で指定したパターンを抽出。抽出したパターンは$1$2で参照。 Pattern.compile("(abc)(def)").matcher("abcdef").group()
Ruby 括弧()で指定したパターンを抽出。抽出したパターンは$1$2で参照。 "abcdef".match(/(abc)(def)/)
Go 括弧()で指定したパターンを抽出。抽出したパターンは$1$2で参照。 regexp.MustCompile("(abc)(def)").FindStringSubmatch("abcdef")
PHP 括弧()で指定したパターンを抽出。抽出したパターンは$1$2で参照。 preg_match('/(abc)(def)/', "abcdef", $matches);

応用一覧

特定のパターン(Eメール、URL、CSSの色コード、電話番号など)を認識する正規表現は、詳細な検証や特定の規格を完全にカバーするものではないことを理解しておいてください。これらは基本的な検証には役立つものの、特定の規格を厳密に準拠する形式を確認する場合には、専用のライブラリやサービスを使用することをお勧めします。

※ ここでの “=>” は言語非依存の表現として使っています。具体的なプログラムのコードでは、文字列の置換を行う関数やメソッドを使用してください。

正規表現 説明 置換例
^\d+$ 一つ以上の数字のみから成る文字列にマッチする。 '123' => '456'
^\s*$ 空白文字のみ(または空文字列)にマッチする。 ' ' => ''
^[a-zA-Z]+$ 英字のみから成る文字列にマッチする。 'abc' => 'def'
^[0-9a-zA-Z]+$ 英字と数字のみから成る文字列にマッチする。 'abc123' => 'def456'
^\w+$ 単語(英字、数字、アンダースコア)のみから成る文字列にマッチする。 'abc_123' => 'def_456'
^\W+$ 非単語文字のみから成る文字列にマッチする。 '@@@' => '###'
^[\d\.]+$ 数字とピリオドのみから成る文字列にマッチする。 '123.456' => '789.012'
^[0-9a-fA-F]+$ 16進数のみから成る文字列にマッチする。 'abc123' => 'def456'
^\b\w+\b$ 単語境界で区切られた単語にマッチする。 'word' => 'newWord'
^\d{10}$ ちょうど10個の数字から成る文字列にマッチする。 '1234567890' => '0987654321'
^[a-z]{5,10}$ 小文字の英字で、5~10文字の長さの文字列にマッチする。 'abcdefgh' => 'ijklmnop'
^\d{2,}$ 2文字以上の数字のみから成る文字列にマッチする。 '12' => '34'
^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$ IPv4 アドレスにマッチする。 '192.168.1.1' => '10.0.0.1'
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$ 最低1つの小文字と1つの大文字と1つの数字を含み、かつ最低8文字以上の文字列にマッチする(パスワード検証によく使われる) 'Passw0rd' => 'NewP4ssword'
^[0-7]+$ 8進数のみから成る文字列にマッチする。 '123' => '456'
^[\w\d\s\.-_]+@[\w\d\.-]+\.[\w\d\._-]+$ Eメールアドレスにマッチする。 'user@example.com' => 'newUser@new.example.com'
^(http URLにマッチする。 https)://[^ "]+$
^#?([a-f0-9]{6} CSSの色コード(#ffffffまたは#fff形式)にマッチする。 [a-f0-9]{3})$
^(\+?\d{1,4}[-.])?\(?\d{1,3}?\)?[-.\d]*$ 電話番号にマッチする。 '+1-800-123-4567' => '+1-800-765-4321'

注意事項

  1.  複雑なパターン
    正規表現は複雑なパターンを表現するためのツールであり、その複雑さは理解やメンテナンスを困難にすることがある。必要以上に複雑な正規表現を使用すると、コードの読みやすさが損なわれ、バグの原因となる。
  2.  パフォーマンス
    正規表現の一部は「貪欲」で、可能な限り多くの文字にマッチしようとする。これは大きなテキストに対して非効率であったり、時間がかかる場合がある。
  3.  全体的なマッチ
    正規表現はデフォルトで全体の文字列に対してマッチングを試む。そのため、部分的なマッチを期待している場合には注意が必要。
  4.  セキュリティ:
    正規表現をユーザー入力の検証に使う場合、特にセキュリティを確保することが重要。正規表現を正しく設定しないと、予期しない入力が許可され、それがセキュリティの脆弱性につながる可能性がある。
  5.  特殊な文字のエスケープ:
    正規表現では、いくつかの文字が特別な意味を持つ(例えば、”.”や”*”)。これらの文字をリテラルとして扱いたい場合は、バックスラッシュ(\)でエスケープする必要がある。
  6.  マルチラインの扱い
    正規表現のデフォルトの動作は一行に対するもので、マルチラインのテキストを扱う場合には特別な考慮が必要。
  7.  クロスプラットフォームの互換性
    正規表現の挙動はプログラミング言語やプラットフォームによって異なる場合がある。したがって、正規表現を別の環境で再利用する場合には、その環境での挙動を確認することが重要。
以上のような点を考慮に入れつつ、必要な場合には正規表現を利用してパターンマッチングやテキスト処理を行うことができまる。
YouTubeのチャンネル登録はこちら!!
( *ˊᵕˋ)σ 凸ポチッと応援よろしくね!!
開発・運営ランキング にほんブログ村 IT技術ブログ IT技術情報へ
記事を書いてる人
病根のバグ

ガラケー時代からWEB開発やってるバツイチ自宅SEです。不眠不休で働くので、ブログのブックマークとYouTubeのチャンネル登録とXのフォローお願いします。デスマ上等!!

「○○を知りたい!!」「○○が分からない!!」などありましたら、Twitterでもブログでもコメントいただければ、ご期待に添えるように頑張ります!

病根のバグのSNSを覗く!!
JavaScript
病根のバグのSNSを覗く!!
ITkagyo

コメント

タイトルとURLをコピーしました