正規表現リファレンス(CoffeeScript)

正規表現はパターンとフラグを/で区切って記述します。フラグは指定しなくても構いません。

/パターン/フラグ

フラグ

フラグには以下の文字が指定可能です。

g

最初の1個だけでなく、文字列の最後まで検索を繰り返します。「グローバルマッチ」とも呼ばれます。

文字列.replaceメソッドでgフラグを指定すると、見つかったすべての部分文字列が置換されます。

# 最初のaaだけが置換される
"aabbaabb".replace(/aa/, "cc")
# => 'ccbbaabb'
# すべてのaaが置換される
"aabbaabb".replace(/aa/g, "cc")
# => 'ccbbccbb'

i

大文字小文字を区別せずにマッチします。

# 大文字のXYZにのみマッチする
/XYZ/.test("xyz")
# => false
# 大文字小文字に関係なくXYZにマッチする
/XYZ/i.test("xYz")
# => true

m

^$がそれぞれ行頭と行末にもマッチするようになります。

# $は文字列の末尾にのみマッチする
/^hello$/.test("hello\nworld")
# => false
# $は文字列の末尾と行末にマッチする
/^hello$/m.test("hello\nworld")
# => true

フラグは組み合わせ可能

フラグを並べて複数指定することもできます。フラグの順番は特に関係ありません。

# 大文字小文字に関係なくabcを探し、それらをdefに置換する
"abcABC".replace(/abc/ig, "def")
# => 'defdef'

特殊文字

パターンの中で使える特殊文字は以下の通りです。ほとんど使われない特殊文字については除外してあります。

^

入力文字列の先頭にマッチします。

/^on/.test("oni")
# => true
/^on/.test("pon")
# => false

$

入力文字列の末尾にマッチします。

/on$/.test("pon")
# => true
/on$/.test("oni")
# => false

.

改行以外の任意の1文字にマッチします。

/a.c/.test("abc")
# => true
/a.c/.test("a@c")
# => true

?

?の直前の文字が出現してもしなくてもマッチします。

/ab?c/.test("ac")
# => true
/ab?c/.test("abc")
# => true

*

*の直前の文字が0個以上連続したものにマッチします。可能な限り長い範囲にマッチします(最長マッチ)。

match = /a.*c/.exec("abbcbc")
# match[0] は 'abbcbc'

*?

*と同じく、直前の文字が0個以上連続したものにマッチしますが、可能な限り短い範囲にマッチします(最短マッチ)。

match = /a.*?c/.exec("abbcbc")
# match[0] は 'abbc'

+

+の直前の文字が1個以上連続したものにマッチします。可能な限り長い範囲にマッチします(最長マッチ)。

/ab+c/.test("abc")
# => true
/ab+c/.test("ac")
# => false

+?

+と同じく、直前の文字が1個以上連続したものにマッチしますが、可能な限り短い範囲にマッチします(最短マッチ)。

match = /a.+?c/.exec("acbcdc")
# match[0] は 'acbc'

{n}

{の直前の文字がn回繰り返されたものにマッチします。

/a{3}b/.test("aaab")
# => true
/a{4}b/.test("aaab")
# => false
# abcabcdにマッチする
/(abc){2}d/.test("abcabcd")
# => true

{n,}

{の直前の文字がn回以上繰り返されたものにマッチします。

/a{2,}b/.test("aab")
# => true
/a{2,}b/.test("aaab")
# => true
/a{2,}b/.test("ab")
# => false

{n,m}

{の直前の文字がn回以上m回以下繰り返されたものにマッチします。

/ab{2,3}c/.test("abbc")
# => true
/ab{2,3}c/.test("abbbc")
# => true
/ab{2,3}c/.test("abbbbc")
# => false

[xyz]

[ ]内のいずれかの文字にマッチします。[ ]内には文字を何個指定しても構いません。

/[kb]ite/.test("kite")
# => true
/[kb]ite/.test("bite")
# => true
/[kb]ite/.test("site")
# => false

[a-z]

aからzまでのいずれかの文字にマッチします。[ ]内では-は文字の範囲を表します。[A-Za-z]のように複数の範囲を指定することも可能です。

/[a-z]/.test("c")
# => true
/^[0-9A-Za-z]*$/.test("plus1")
# => true
/^[0-9A-Za-z]*$/.test("plus 1")
# => false
/^[0-9_]*$/.test("0_123_456")
# => true

[ ]の中で-という文字自体にマッチさせるには、エスケープして\-と記述するか、あるいは[-abc][abc-]のように最初か最後に-を置きます。

/^[-0-9A-Za-z]*$/.test("Test-11")
# => true

また、[ ]内では通常の特殊文字は効果を失い、その文字自体を意味します。例えば[.]は、任意の1文字ではなく、ドット( . )の文字自体にマッチします。

/ab[.]cd/.test("abzcd")
# => false
/[$]100/.test("$100")
# => true

ただし、]\等は[ ]内においても特殊な文字なので、マッチさせるにはエスケープが必要です。

# ]にマッチする
/[\]]/.test("]")
# => true
# \にマッチする
/[\\]/.test("\\")
# => true

[^xyz]

[^ ]内に指定された文字以外の文字にマッチします。

/^[^abc]*$/.test("xyz")
# => true
/^[^abc]*$/.test("axyz")
# => false

(x)

( )内のパターンにマッチして、キャプチャします。キャプチャした文字列は後から参照できます。

match = /a(.*)c(.*)e/.exec("abbbcddde")
# match[1] は 'bbb'
# match[2] は 'ddd'

また、( )はパターンをグループ化する役割も持っており、特殊文字の適用範囲を変えることができます。下の例では?( )内に対して有効となります。

/abc(def)?ghi/.test('abcdefghi')
# => true
/abc(def)?ghi/.test('abcghi')
# => true

文字列.replaceメソッドの第2引数内で$1$2を指定すると、キャプチャした文字列を参照できます。$1$2といった数字はパターン内での(の出現順に対応しています。

# 単語を入れ替える
re = /([a-z]+) and ([a-z]+)/
"night and day".replace(re, "$2 and $1")
# => 'day and night'

(?:x)

(x)と同様にグループ化が行われ、xにマッチしますが、キャプチャは行われません。

/abc(?:def)?ghi/.test("abcdefghi")
# => true
/abc(?:def)?ghi/.test("abcghi")
# => true

キャプチャがあると処理時間が若干長くなるため、「キャプチャは不要だがグループ化は必要」という場合はなるべくこの記述方法を使うとよいでしょう。

x|y

|で区切られたパターンのいずれかにマッチします。何個でも|で区切って並べることができます。

/abc|def/.test("abc")
# => true
/abc|def/.test("def")
# => true

( )の内側で使うと、( )の範囲内に対してのみ有効になります。

/ab(cd|ef|gh)ij/.test("abcdij")
# => true

x(?=y)

xの後ろにyが続く場合のみ、xにマッチします。マッチ結果にyは含まれません。

# マッチする
"abcde".replace(/bcd(?=e)/, "zzz")
# => 'azzze'
# マッチしない
"abcdz".replace(/bcd(?=e)/, "zzz")
# => 'abcdz'

x(?!y)

xの後ろにyが続かない場合のみ、xにマッチします。

# マッチする
"abcde".replace(/bcd(?!z)/, "zzz")
# => 'azzze'
# マッチしない
"abcdz".replace(/bcd(?!z)/, "zzz")
# => 'abcdz'

\b

英単語の境界となる箇所にマッチします。行頭や行末の他に、空白や記号などといった英単語を区切る文字も境界として扱われます。

# andという語にマッチする正規表現
/\band\b/.test("and")
# => true

/\band\b/.test("sand")
# => false

/\band\b/.test("a and b")
# => true

/\band\b/.test("<and>")
# => true

\B

単語の境界ではない箇所にマッチします。\bの反対です。

# 単語の2文字目以降にあるandという文字の並びにマッチする
/\Band/.test("sand")
# => true

/\Band/.test("and")
# => false

\d

0から9までの半角数字にマッチします。[0-9]と同じ意味です。

/\d{3}/.test("246")
# => true
/^\d+$/.test("1185")
# => true

\D

半角数字以外の文字にマッチします。\dの反対です。

/\D/.test("abc")
# => true
/\D/.test("012")
# => false

\n

ラインフィード(Line Feed、LF)と呼ばれる改行文字にマッチします。UNIXやLinux、Mac OS X等では改行文字として\nが使われています。

/hello\nworld/.test("hello\nworld")
# => true

\r

キャリッジリターン(Carriage Return、CR)と呼ばれる改行文字にマッチします。Mac OS 9までの古いMac OSでは改行文字として\rが使われていました。また、Windowsでは改行文字として\r\nが使われています。

/hello\r\nworld/.test("hello\r\nworld")
# => true

\s

空白文字にマッチします。空白文字とは、スペースやタブ文字、改行文字などです。

/you\s+are/.test("you are")
# => true
/you\s+are/.test("you   are")
# => true

\S

空白文字以外の文字にマッチします。\sの反対です。

/^\S+$/.test("abc")
# => true
/^\S+$/.test("   ")
# => false

\t

タブ文字にマッチします。

/Tea\t100/.test("Tea\t100")
# => true

\w

単語構成文字にマッチします。[A-Za-z0-9_]と同じ意味です。

/^\w+$/.test("hello")
# => true
# !にはマッチしない
/^\w+$/.test("hello!")
# => false

\W

単語構成文字以外の文字にマッチします。[^A-Za-z0-9_]と同じ意味です。\wの反対です。

/\W/.test("hello!")
# => true
/\W/.test("hello")
# => false

\1、\2、…

グループを使ってキャプチャした文字列をパターン内で参照するときに使います。

/(a+)b+(c+)d+\1\2/.test("aabbccddaacc")
# => true
/(a+)b+(c+)d+\1\2/.test("aabbccddac")
# => false

エスケープ

特殊文字の意味を打ち消す(エスケープする)には、特殊文字の直前に\を置きます。

/\$100/.test("$100")
# => true
uri = "http://www.example.com/123"
/^http:\/\/www\.example\.com\/\d+/.test(uri)
# => true

メソッド

正規表現が使える主なメソッドは以下の通りです。

正規表現.test(文字列)

文字列が正規表現にマッチするかどうかを調べます。マッチすればtrue、マッチしなければfalseが返ります。

/[abc]/.test("a")
# => true
/[xyz]/.test("a")
# => false

正規表現.exec(文字列)

文字列に対して正規表現によるマッチを試み、マッチ結果を返します。マッチしなかった場合はnullを返します。

result = /a(b+)c(d+)e/.exec("_abbbcddefg")
if result?
  console.log result[0]  # マッチした文字列
  console.log result[1]  # 1番目のキャプチャ
  console.log result[2]  # 2番目のキャプチャ
else
  console.log "マッチせず"

【実行結果】

abbbcdde
bbb
dd

gフラグを付けて複数回呼ぶことで、文字列の末尾に達するまでマッチを繰り返せます。

re = /\d+/g  # 半角数字にマッチする
str = 'abc111def222xyz'

while (m = re.exec(str))?
  console.log "Found #{m[0]} at #{m.index}"

【実行結果】

Found 111 at 3
Found 222 at 9

文字列.replace(正規表現, 新しい文字列または関数)

第2引数に文字列を指定した場合は、正規表現にマッチした部分を新しい文字列で置き換えます。正規表現にgフラグを指定すると、最初にマッチした箇所だけでなく、すべてのマッチ箇所が置換されます。

# 最初のaをzに置換
"abcba".replace(/a/, "z")
# => 'zbcba'

# すべてのaを置換
"abcba".replace(/a/g, "z")
# => 'zbcbz'

一方、第2引数に関数を指定した場合は、正規表現にマッチした部分が関数の戻り値で置き換えられます。関数の第1引数にはマッチした部分文字列が渡され、第2引数以降にはキャプチャした文字列が渡されます。

# 数字をそれぞれ2倍、3倍する
re = /(\d+) x (\d+)/
str = "100 x 200".replace re, (match, p1, p2) ->
  "#{p1 * 2} x #{p2 * 3}"

console.log str

【実行結果】

200 x 600

gフラグを付けると、文字列の末尾に達するまで繰り返しマッチが行われます。マッチするたびに関数が呼び出され、その部分が戻り値で置き換えられます。

# 数字に100を足す
str = "100 yen and 200 yen"
out = str.replace /\d+/g, (match) ->
  parseInt(match, 10) + 100

console.log out

【実行結果】

200 yen and 300 yen

関数の引数のうち後ろから2つはそれぞれ、マッチした位置と、元の文字列全体です。上の例のように、これらの引数が不要な場合は受け取らなくても構いません。

str = "100 yen and 200 yen"
out = str.replace /\d+/g, (m, pos, str) ->
  # posはマッチした位置
  # strは元の文字列全体
  console.log "match: #{pos} in \"#{str}\""
  parseInt(m, 10) + 100

console.log out

【実行結果】

match: 0 in "100 yen and 200 yen"
match: 12 in "100 yen and 200 yen"
200 yen and 300 yen

文字列.split(正規表現)

正規表現にマッチした部分で文字列を区切り、配列にして返します。

# 数字で区切って配列にする
"a1b2c3d".split(/\d/)
# => [ 'a', 'b', 'c', 'd' ]

文字列.match(正規表現)

文字列に対して正規表現によるマッチを試み、マッチ結果を返します。マッチしなかった場合はnullを返します。

result = "_abbbcddefg".match(/a(b+)c(d+)e/)
if result?
  console.log result[0]  # マッチした文字列
  console.log result[1]  # 1番目のキャプチャ
  console.log result[2]  # 2番目のキャプチャ
else
  console.log "マッチせず"

【実行結果】

abbbcdde
bbb
dd

正規表現.exec(文字列)メソッドとの違いは、gフラグを指定した場合にマッチ結果が一度にまとめて配列で返ってくる点です。

"789".match(/\d/g)
# => [ '7', '8', '9' ]

execメソッドの場合は複数回呼び出す必要があります(参考)。

文字列に対してマッチを試み、マッチしたインデックスを返します。マッチしなかった場合は-1を返します。インデックスは0から数え始めます。

"0az".search(/[abc]/)
# => 1

使用例

正規表現の使用例を以下に示します。

年月日を抜き出す

「2013/5/19」といった文字列から年月日の数字を抽出します。

match = /(\d+)\D+(\d+)\D+(\d+)/.exec("2013/5/19")
[year, month, date] = match[1..3]
console.log "#{year}年#{month}月#{date}日"

【実行結果】

2013年5月19日

ファイル名の拡張子を抜き出す

ファイル名のうち、拡張子の部分だけを抽出します。

match = /.*\.([^.]+)/.exec("neko.jpg")
if match?
  extension = match[1]
  console.log extension

【実行結果】

jpg

特定の英単語を< >で囲う

isという語を<b></b>で囲みます。単語の内部に出現するisという文字の並び(Thisなど)にマッチしないようにするため、\bを使います。

str = "This is blue. That is red."
out = str.replace(/\b(is)\b/g, "<b>$1</b>")
console.log out

【実行結果】

This <b>is</b> blue. That <b>is</b> red.