🌊

【JavaScript】正規表現を手軽に扱うための基礎入門

2024/09/21に公開

モチベーション

  • 正規表現を敬遠していたが扱えるようになりたい
  • 文字列一致しているかを実装する時に使いたい
    • 郵便番号や電話番号
    • HTMLパース
    • ログ解析
    • など
  • VSCodeなどのエディタで検索する時に使えると便利

環境

  • macOS: Sonoma
  • 言語: JavaScript
    • ※プログラム言語によって仕様が異なる部分があるので、よく使うことが多そうなJavascriptを用いて検証していきます
  • node: 21.4.0

指定した文字列に一致

文字列

console.log(/abc/.test("aaaa"))
// false
console.log(/abc/.test("abcd"))
// true

数字

console.log(/123/.test("1111"))
// false
console.log(/123/.test("1234"))
// true

全ての文字列に一致: .

.は何でも一致です

console.log(/./.test("123abc"))
// true
console.log(/./.test("_/[]%@"))
// true

指定したいずれかに一致: []

ブラケット[]内に文字を指定するといずれかが一致すればマッチしたという判定になります

console.log(/[1aA]/.test("0BC%"))
// false
console.log(/[1aA]/.test("1BC%"))
// true

指定した範囲内のいずれかに一致: [-]

[○-○]で範囲の指定もできます

console.log(/[0-4]/.test("0BC%"))
// true
console.log(/[a-dA-D]/.test("1BC%"))
// true

範囲指定はASCIIコードの範囲を指定しています (ASCIIコード表)
なので以下の様に一見、英字のみの一致条件に見えますがブラケットやアンダースコアも一致します

console.log(/[A-z]/.test("[]_"))
// true

指定したいずれか以外に一致: [^]

[]で先頭に^をつけるといずれか以外の一致になります

console.log(/[^1aA]/.test("AAAaa11"))
// false
console.log(/[^1aA]/.test("0BC%"))
// true

[]の先頭以外につけてしまうと単にハット記号^扱いになるので注意

console.log(/[1^aA]/.test("AAAaa11"))
// true

任意の数字が一致: \d

任意の数字は[0-9]でも指定できますが、\dでも同じ働きをします
※ d = digit なので数字という意味になります

console.log(/\d/.test("ABC"))
// false
console.log(/\d/.test("123"))
// true

数字以外の一致: \D

\Dで数字以外の一致
大文字になると反対を意味する、とすると覚えやすいです

console.log(/\D/.test("123"))
// false
console.log(/\D/.test("ABC"))
// true

任意の文字が一致: \w

任意文字の場合は\wとすると大文字小文字の英語、数字、アンダースコアとマッチしてくれます
※w = word みたいなのですがあまりしっくりは来ていません

console.log(/\w/.test("A1_"))
// false
console.log(/\w/.test("$@/"))
// true

文字以外の一致: \W

\Wで文字以外(\w以外)の一致

console.log(/\w/.test("%@/"))
// false
console.log(/\w/.test("A1_"))
// true

直前の文字が0 or 1回出現で一致: ?

?で直前の文字が1回だけあるもしくはない時にマッチさせることができます

console.log(/ab?c/.test("ab"))
// false
console.log(/ab?c/.test("abbc"))
// false
console.log(/ab?c/.test("abc"))
// true
console.log(/ab?c/.test("ac"))
// true

直前の文字が0回以上出現で一致: *

*で直前の文字が1回以上の連続出現もしくはない時にマッチさせることができます

console.log(/ab*c/.test("ab"))
// false
console.log(/ab*c/.test("abbc"))
// true
console.log(/ab*c/.test("abc"))
// true
console.log(/ab*c/.test("ac"))
// true

直前の文字が0回以上出現で一致: +

+で直前の文字が1回以上の連続出現時にマッチさせることができます

console.log(/ab+c/.test("ab"))
// false
console.log(/ab+c/.test("abbc"))
// true
console.log(/ab+c/.test("abc"))
// true
console.log(/ab+c/.test("ac"))
// false

直前の文字が指定した回数出現で一致: {}

{min, max}で直前の文字がmin回以上max回以下の連続出現時にマッチさせることができます

console.log(/ab{2,4}c/.test("abc"))
// false
console.log(/ab{2,4}c/.test("abbbc"))
// true
console.log(/ab{0,2}c/.test("ac"))
// true

行頭の一致: ^

^で行の先頭が指定して文字列をマッチさせることができます

console.log(/^abc/.test("123abc"))
// false
console.log(/^abc/.test("abc123"))
// true

行末の一致: $

$で行の文末が指定して文字列をマッチさせることができます

console.log(/abc$/.test("abc123"))
// false
console.log(/abc$/.test("123abc"))
// true

1文字より大きい文字数の一致: ()

()でマッチ対象の文字列をグループ化して、そのグループに対してマッチさせることができます

console.log(/(ab)+c/.test("c"))
// false
console.log(/(ab)+c/.test("ababc"))
// true
console.log(/(a[1-3])+c/.test("a0c"))
// false
console.log(/(a[1-3])+c/.test("a1c"))
// true

論理和

(|)でグループ内のいずれかのみを対象にすることができます

console.log(/(ab|12)+c/.test("aac"))
// false
console.log(/(ab|12)+c/.test("abc"))
// true
console.log(/(ab|12)+c/.test("11c"))
// false
console.log(/(ab|12)+c/.test("12c"))
// true

キャプチャ

()はキャプチャグループといい、キャプチャした文字列を取得することができます

const matches = "123-4567".match(/(\d+)-(\d+)/)
console.log(matches[1])
// 123
console.log(matches[2])
// 4567

それぞれのキャプチャグループは?<名前>で名前をつけることもできます

const matches = "123-4567".match(/(?<first>\d+)-(?<second>\d+)/)
console.log(matches.groups.first)
// 123
console.log(matches.groups.second)
// 4567

その他の特殊文字の一致

  • \nで改行にマッチ

  • \rでキャリッジリターンにマッチ

  • \tでタブにマッチ

  • \sで半角スペースにマッチ

  • \Sで半角スペース以外にマッチ

使い方は\d\wと同じです

オプションフラグ(Javacript)

JavaScriptでは正規表現の後ろにオプションを付けることができます

グローバルマッチ: /g

/gは指定された文字列が対象に複数回あっても全てマッチしてくれます
/gがなければ1回のみです

const matches = "20.4.0".match(/\.\d+/)
console.log(matches[0])
// .4
console.log(matches[1])
// undefined
const matches = "20.4.0".match(/\.\d+/g)
console.log(matches[0])
// .4
console.log(matches[1])
// .0

大文字・小文字を区別しない: /i

/iは英字の大文字と小文字を区別せずマッチしてくれます

console.log(/abc/.test("ABc"))
// false
console.log(/abc/i.test("ABc"))
// true

複数行: /m

/mは複数行にわたって検索してマッチしてくれます

console.log(/^abc/.test("123\nabc"))
// false
console.log(/^abc/m.test("123\nabc"))
// true

まとめ

よく使いそうな正規表現をまとめてみました
こちらを参考に実際にどんどん手を動かして正規表現を手軽に使えるようになりましょう
こちらのサイトは手を動かしながら練習できるのでおすすめです
https://regexone.com/

参考資料

https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_expressions

https://qiita.com/iLLviA/items/b6bf680cd2408edd050f

GitHubで編集を提案

Discussion