Ruby 2.4.0 リファレンスマニュアル > 正規表現

正規表現

正規表現(regular expression)は文字列のパターンを記述するための言語です。 また、この言語で記述されたパターンも正規表現と呼びます。

正規表現を用いると、文字列が指定したパターンを含んでいるかどうかを判定し、 また含んでいるならばそれが文字列中のどの場所であるかを知ることができます。

/pat/
%r{pat}

などの正規表現リテラルや Regexp.new などで正規表現 オブジェクトを得ることができます。

メタ文字列とリテラル、メタ文字とエスケープ

正規表現の文法には、正規表現内で特別な働きをする文字列と、それ以外の その文字列そのものにマッチするような文字列があります。 前者をメタ文字列(meta string)、後者をリテラル(文字列)(literal string)と呼びます。

/京都|大阪|神戸/

という正規表現においては、「京都」「大阪」「神戸」がリテラルで、 2つの「|」がメタ文字列です。

以下の文字は「メタ文字」(meta character) と呼ばれる、正規表現内で特殊な働きをする文字です。

( ) [ ] { } . ? + * | \

これらの文字をリテラルのようにその文字としてマッチさせるためには、 バックスラッシュ「\」を前に付けます。「\\」はバックスラッシュ1文字に マッチします。

メタ文字以外の文字も、メタ文字に続けて置くことで特別な働きをするよう になる場合があります。つまりメタ文字列を構成します。例えば

/[a-z]/
/\Axyz\Z/

という正規表現において "[a-z]", "\A", "\Z"はメタ文字列です。

式展開

正規表現内では、#{式} という形式で式を評価した文字列を埋め込むことが できます。

place = "東京都"
/#{place}/.match("Go to 東京都") # => #<MatchData "東京都">

埋め込んだ文字列にメタ文字が含まれているならば、それは メタ文字として認識されます。

number = "(\\d+)"
operator = "(\\+|-|\\*|/)"
/#{number}#{operator}#{number}/.match("43+291")
# => #<MatchData "43+291" 1:"43" 2:"+" 3:"291">

埋め込む文字列をリテラルとして認識させたい場合は Regexp.quote を 使います。

文字

正規表現内では、「\」の後に文字列を置くことで、 ある特定の文字を表現することができます。 これは、改行のように Ruby の文法で特別な意味を持つ文字を埋め込む ためなどに用いられます。 文字列リテラルの記法とほぼ同様(リテラル/バックスラッシュ記法)で、 以下の記法が利用可能です。

\t           水平タブ            horizontal tab (0x09)
\v           垂直タブ            vertical tab   (0x0B)
\n           改行                newline        (0x0A)
\r           復帰                return         (0x0D)
\b           バックスペース      back space     (0x08)
\f           改ページ            form feed      (0x0C)
\a           ベル                bell           (0x07)
\e           エスケープ文字      escape         (0x1B)
\nnn         符号化バイト値の8進数表現 (nnn の8進数3文字で表現)
\xHH         符号化バイト値の16進数表現 (HH の16進数2文字で表現)
\cx, \C-x    制御文字 (x は a から z までのいずれかの文字)
\M-x         メタ (x|0x80)
\M-\C-x      メタ制御文字
\uHHHH       ユニコード文字 (HHHH の16進数4桁)
\u{HHHHHH HHHHHH ....} ユニコード文字列 (HHHHHH は16進数1桁から6桁まで指定可能)

\b は文字クラス内でのみ有効な表現です。文字クラスの外では 単語の区切りを表すメタ文字列と解釈されます。

「\s」は文字列では空白(0x20)を意味しますが、正規表現では タブなどを含む空白文字全般にマッチするメタ文字列です。

任意の1文字

メタ文字 . は改行を除く任意の1文字にマッチします。

ただし、オプション m によって改行にもマッチするようになります。

文字クラス

文字クラス(character class) とは角括弧 [ と ] で囲まれ、1個以上の文字を列挙したもので、 いずれかの1文字にマッチします。

/W[aeiou]rd/

は Ward, Werd, Wird, Word, Wurd のいずれかにマッチします。

文字クラス内のハイフン(-)は文字の範囲を表すメタ文字です。 例えば [abcd] という文字クラスは [a-d] と表すことができます。 複数の範囲指定をすることもできます。例えば [abcdpqrs] は [a-dp-s]と 表すこともできます。

文字クラスの [ の直後の文字がキャレット(^)である場合、列挙「されていない」 文字にマッチするようになります(これは否定文字クラスと呼ばれます)。

[^a-d]

はabcd以外の1文字にマッチします。

文字クラス内に別の文字クラスを含めることができます。 [a-z[0-9]] は [a-z0-9]と同じ意味を持ちます。これだけではあまり意味が ありませんが、文字クラスは && という、共通部分を取る演算をサポートして いるため、これと組合せることで意味を持ちます。

/[a-z[0-9]]/.match("y") # => #<MatchData "y">
/[a-z[0-9]]/.match("[") # => nil
r = /[a-w&&[^c-g]e]/ # ([a-w] かつ ([^c-g] もしくは e)) つまり [abeh-w] と同じ
r.match("b") # => #<MatchData "b">
r.match("c") # => nil
r.match("e") # => #<MatchData "e">
r.match("g") # => nil
r.match("h") # => #<MatchData "h">
r.match("w") # => #<MatchData "w">
r.match("z") # => nil

文字クラスでは、否定(^)範囲(-)共通部分(&&)列挙(並べる)という 演算が可能ですが、これらは - > (列挙) > && > ^ という順の結合強度を持ちます。

文字クラス内の3つのメタ文字を通常の文字の意味で使用したい場合には、 \ によってエスケープ する必要があります。

文字クラスの略記法

良く使われる文字クラスには省略記法が存在します。

これらの「空白」「数字」などは ASCII の範囲の文字のみを対象としています。 いわゆる「全角アルファベット」「全角空白」「全角数字」などは ここの空白、数字、には含まれません。

/\w+/.match("ABCdef") # => nil
/\W+/.match("ABCdef") # => #<MatchData "ABCdef">
/\s+/.match(" ") # => nil
/\S+/.match(" ") # => #<MatchData " ">

これらは文字クラス内で演算することもできます。

r = /[\d&&[^47]]/ # 4, 7 以外の数字
r.match("3") # => #<MatchData "3">
r.match("7") # => nil

Unicode プロパティによる文字クラス指定

また、Unicodeのプロパティ(属性情報)による文字クラス指定も可能です。 以下の記法が使えます。

サポートされているプロパティのリストは https://github.com/k-takata/Onigmo/blob/master/doc/UnicodeProps.txt を 参考にしてください。また、プロパティの意味は Unicode の仕様を参照してください。

/\p{Letter}+/.match(".|あaABc123") # => #<MatchData "あaABc">

POSIX 文字クラス

Unicodeプロパティと 似た機能を持つ記法として、POSIX 文字クラスと呼ばれるものがあります。 これらは上の省略記法とは異なり、文字クラスの中でしか用いることが できません。これらは [:クラス名:] という記法を持ちます。 また、[:^クラス名:]という記法でその否定を意味します。 以下の括弧では実際にどの文字にマッチするかが Unicode プロパティや Unicode コードポイントで示されています。

これらの POSIX 文字クラスは \s といった省略記法と異なり、 ASCIIコード範囲外の空白などを考慮に入れます。

/[[:alnum:]]+/.match("abAB121") # => #<MatchData "abAB121">
# \u3000 は全角空白
/[[:graph:]]/.match("\u3000") # => nil
/[[:blank:]]/.match("\u3000") # => #<MatchData " ">
/[[:alnum:]&&[:^lower:]]/.match("aA") # => #<MatchData "A">
/[[:print:]&&[:^lower:]]/.match(" ") # => #<MatchData " ">

注: POSIX ではここで言う文字クラスのことを「ブラケット表現」と 呼び、[:xxx:] というのを文字クラス、と呼んでいます。よって、 POSIX文字クラス、というのは厳密には 「POSIXブラケット表現における文字クラス」と呼ぶべきものですが、 ここでは「POSIX文字クラス」と呼ぶことにします。

注: [:word:] と [:ascii:] は POSIX では定義されていません。 Ruby/Oniguruma/Onigmo独自のものです。

注: エンコーディングによってこれらの POSIX 文字クラスの挙動が 異なります。上に書いている「マッチする文字」は Unicode 系統の エンコーディングで使われるものです。 Unicode 系統以外のものは Onigmo の ドキュメントを参照してください。

オプション

文字クラスの挙動は オプション で変更することができます。 d, a, u の3つのオプションがあります。

特別な文字列に対するマッチ

文字列の中には、CR LF のように、複数の文字一続きで1つの意味を表す ようなものが存在します。そのような文字列にマッチするような メタ文字列として以下が存在します。

# \u{0308} はウムラウト
/\X/.match("e\u{0308}") # => #<MatchData "ë">
$&.codepoints # => [101, 776]
/\w/.match("e\u{0308}") # => #<MatchData "e">
$&.codepoints # => [101]

繰り返し

以下のメタ文字列は繰り返しを表現します。 直前の部分式を何回繰り返すかを指定します。このような繰り返しを 表すメタ文字列を量指定子(quantifier)と呼びます。

以下の例で、量指定子の基本的な使いかたを示しています。

# 以下の正規表現は 最初に大文字が1文字以上(H)で、小文字が1文字以上(l)、
# lが2文字(ll)の後ろにoが続く文字列にマッチします。
"Hello".match(/[[:upper:]]+[[:lower:]]+l{2}o/) # => #<MatchData "Hello">

これらは「欲張り(greedy)」にマッチします。 マッチが成功する、最長の文字列にマッチしようとします。 そのため、これらの量指定子は特に最大量指定子(greedy quantifier) と呼ばれます。

最小量指定子(reluctant quantifier)

一方、以下のメタ文字列(普通の繰り返しメタ文字列に ? を付加したもの) はマッチが成功する、最短の文字列にマッチします。そのため、これらの 量指定子は特に最小量指定子(reluctant quantifier)と呼ばれます。

以下の例では、最小量指定子を使うことで、(\d+)がマッチする場所を変えています。

/^.*(\d+)\./.match("Copyright 2013.")  # => #<MatchData "Copyright 2013." 1:"3">
/^.*?(\d+)\./.match("Copyright 2013.")  # => #<MatchData "Copyright 2013." 1:"2013">

また、ネストしていない括弧の対応を取るためにも使えます。

# ここでは <b> と </b> の対応を取る
%r{<b>.*</b>}.match("<b>x</b>y<b>z</b>") # => #<MatchData "<b>x</b>y<b>z</b>">
%r{<b>.*?</b>}.match("<b>x</b>y<b>z</b>") # => #<MatchData "<b>x</b>">

絶対最大量指定子(possessive quantifier)

以下のメタ文字列は、最大量指定子のように最長のマッチをしますが、 一度マッチすると、その後マッチに失敗してもバックトラックしません。 つまりマッチ済みの文字列を手放さずにマッチに失敗します。 これらの量指定子は絶対最大量指定子と呼ばれます。

アトミックグループを用いることで同じことができます。

キャプチャ

丸括弧 ( ) によってキャプチャをすることができます。 括弧に囲まれた部分正規表現にマッチした 前からn番目の開き括弧によって囲まれた部分式にマッチした 文字列を後で参照することができます。

正規表現内では \1, \2, ... という記法で後方参照できます。 また、\k<1>, \k<2>, ... や \k'1', \k'2', ... という記法を使うこと もできます(10を越える数字を渡すことができます)。 また、Regexp#match で得られた MatchData からは MatchData#[]で取り出せます。

また、$1, $2, ... という特殊変数によって n 番目の括弧にマッチした 部分文字列を参照できます。これらの特殊変数はマッチ処理が終わったあとで しか使えないことに注意してください。

# (..) に at がマッチしたのを \1 で参照し、マッチが成功している。
m = /[csh](..) [csh]\1 in/.match("The cat sat in the hat")
# => #<MatchData "cat sat in" 1:"at">
# Regexp#match でマッチしたテキストは MatchData#[] で参照できる
m[1] # => "at"

1,2,... ではなく、名前を付けることができます。 (?<name>pat)もしくは(?'name'pat)と記述します。キャプチャした文字列は MatchData#[]Symbol を渡すことで参照できます。 これは名前付きキャプチャと呼ばれます。

m = /\$(?<dollars>\d+)\.(?<cents>\d+)/.match("$3.67")
# => #<MatchData "$3.67" dollars:"3" cents:"67">
m[:dollars] # => "3"
m[:cents] # => "67"

名前付きキャプチャは正規表現内で \k<name>、\k'name' という記法で参照できます。

/(?<vowel>[aeiou]).\k<vowel>.\k<vowel>/.match('ototomy')
# => #<MatchData "ototo" vowel:"o">

注: 名前付きキャプチャと数字によるキャプチャは併用できません。

リテラル正規表現内に名前付きキャプチャがあり、 =~ の左辺で用いた 場合には、その名前のローカル変数にキャプチャした文字列を 代入します。

/\$(?<dollars>\d+)\.(?<cents>\d+)/ =~ "$3.67" # => 0
dollars # => "3"
cents # => "67"

注: ローカル変数への代入が行われるのは、左辺の正規表現リテラルが#{}による式展開を含んでいない場合に限られます。

数字による後方参照では、負の数による、 \k<-1>, \k<-2>, ... や \k'-1', \k'-2', ... という記法での 相対的な指定が可能です。-1 は後方参照が書かれた位置の1つ手前の 位置にあるキャプチャを表し、-2, -3, で2つ手前、3つ手前を表します。 これは非常に多くのキャプチャを持つような正規表現を記述するためや、 正規表現に別の正規表現を式展開で埋め込む場合などに便利です。

/(.)(.)\k<-2>\k<-1>/.match("xyzyz") # => #<MatchData "yzyz" 1:"y" 2:"z">

グループ

丸括弧は部分式をグループ化するためにも使えます。( ) で囲まれた 部分式は一つのものとして取り扱われ、量指定子などを続けて書くことができます。

# The pattern below matches a vowel followed by 2 word characters:
# 'aen'
/[aeiou]\w{2}/.match("Caenorhabditis elegans") #=> #<MatchData "aen">
# Whereas the following pattern matches a vowel followed by a word
# character, twice, i.e. <tt>[aeiou]\w[aeiou]\w</tt>: 'enor'.
/([aeiou]\w){2}/.match("Caenorhabditis elegans")
    #=> #<MatchData "enor" 1:"or">

(?:pat) という記法を使うとキャプチャせずにグループ化することができます。 性能が多少改善する場合がありますが、多少見にくくなります。

# 最初のキャプチャは n で二番目のキャプチャが ti であり、
# \2 で二番目のキャプチャを後方参照しています
/I(n)ves(ti)ga\2ons/.match("Investigations")
    # => #<MatchData "Investigations" 1:"n" 2:"ti">
# 最初のグループは (?: ) を使っているのでキャプチャが作られず、
# 1番目は ti がキャプチャされます。
# そして ti を \1 で参照しています。
/I(?:n)ves(ti)ga\1ons/.match("Investigations")
    # => #<MatchData "Investigations" 1:"ti">

アトミックグループ(atomic grouping)

(?>pat) という記法で「アトミック」なグループを作れます。

通常の正規表現では、ある部分式がマッチに成功した後、 続く式がマッチに失敗した場合、 バックトラックによって成功した部分の一部を手放して マッチにリトライします。 しかし、アトミックなグループがマッチした後、 後続の式がマッチに失敗した場合、一部だけを バックトラックで巻き戻すのではなく、 このグループのマッチ全体を巻き戻します。 つまり、正規表現のマッチのバックトラックを抑制します。

典型的にアトミックグループはバックトラックの回数を減らし 正規表現を高速化するために用います。

# 以下のマッチはまず .* が Quote" にマッチした後、
# 正規表現末尾の " のマッチに失敗します。その後
# 一文字だけバックトラックして、" のマッチに成功します。
/".*"/.match('"Quote"') # => #<MatchData "\"Quote\"">
# 一方、以下のマッチはまず .* が Quote" 全体にマッチした後、
# 正規表現末尾の " のマッチに失敗します。その後
# バックトラックで"がマッチした状態まで戻り、
# (?>.*)以外の選択子がないのでマッチ全体が失敗します。
/"(?>.*)"/.match('"Quote"') # => nil
# 一方、以下のマッチはまず .* が Quote" 全体にマッチした後、
# 正規表現末尾の " のマッチに失敗します。その後
# バックトラックで"がマッチした状態まで戻り、
# 次の可能性(つまり | の右側)のマッチを試します。
# 結果としてマッチが成功します。
/"(?:(?>.*)|(.*))"/.match('"Quote"') # => #<MatchData "\"Quote\"" 1:"Quote">

部分式呼び出し(subexpression call)

\g<name> もしくは \g'name' という記法で、nameと名付けられた部分正規表現にマッチしようとします。 この記法は、部分式呼び出しと呼ばれます。 name には名前、数字、のいずれを用いることもできます。 これは後方参照とは異なります。後方参照は前でマッチした文字列と 同じ文字列にマッチしようとしますが、部分式呼び出しは nameと名付けられた「部分正規表現」にマッチしようとします。

部分式呼び出しの記法は正規表現内に再帰的記述を可能とし、 通常の正規表現では記述不可能な処理(例えば対応した括弧の検出) を可能とします。以下の例では実際に何回かっこがネストしていても マッチに成功します。ただし、再帰的な正規表現を書く場合は、 無限ループに陥る可能性があるため、停止条件に注意して この機能を使ってください。

/\A(?<paren>\(\g<paren>*\))*\z/ =~ '(())' # => 0
# ^1
#      ^2
#           ^3
#                 ^4
#      ^5
#           ^6
#                      ^7
#                       ^8
#                       ^9
#                           ^10
# 1. \A が文字列の先頭にマッチする
# 2. 名前付きキャプチャの内側に入る
# 3. 名前付きキャプチャ内の最初の括弧 \( に文字列の最初の ( マッチする
# 4. \g<paren> で名前付きキャプチャ <paren> にマッチしようとする
# 5. 上の処理の結果(?<paren>pat)に再びマッチしようとする
# 6. \( に前から二番目の ( にマッチする
# 7. \g<paren> でさらに (?<paren>pat) にマッチしようとするが、
#     開き括弧 ( がもう文字列内にないので失敗する。
#    しかし、その後ろに量指定子*があるので、0回マッチとして成功する
# 8. 1つ目閉じ括弧 ) がマッチし、\g<paren>による再帰呼び出し全体が
#    成功する
# 9. 2つ目の閉じ括弧 ) が \) にマッチし、(?<paren>pat)というマッチに成功する
# 10. 文字列の末尾へのマッチに成功する

また、パターン全体は特別に \g<0> もしくは \g'0' という記法で再帰呼び出し できます。番号指定による呼出も可能で、\g<n> もしくは \g'n' という 記法が使えます。相対番号で部分式を指定することもでき、これは \g<-n> \g'-n' (前側での相対位置) や \g<+n> \g'+n' (後側での相対位置) という記法を用います。

以下の記法を用いて、 部分式呼び出しでの上のレベル、下のレベルでのマッチにアクセスすること ができます。levelで呼出しのネストレベルを、nで位置を指定できます。

また、以下の記法で名前付きキャプチャも同様のことができます。

以下の例は回文にマッチする正規表現です。

/\A(?<a>|.|(?:(?<b>.)\g<a>\k<b+0>))\z/.match("rekxker")
# => #<MatchData "rekxker" a:"rekxker" b:"k">

以下の例では、開始タグと終了タグを対応付ける正規表現です。

r = Regexp.compile(<<'__REGEXP__'.strip, Regexp::EXTENDED)
(?<element> \g<stag> \g<content>* \g<etag> ){0}
(?<stag> < \g<name> \s* > ){0}
(?<name> [a-zA-Z_:]+ ){0}
(?<content> [^<&]+ (\g<element> | [^<&]+)* ){0}
(?<etag> </ \k<name+1> >){0}
\g<element>
__REGEXP__
r.match('<foo>f<bar>bbb</bar>f</foo>').captures
# => ["<foo>f<bar>bbb</bar>f</foo>", "<bar>", "bar", "f<bar>bbb</bar>f", "</foo>"]

最左位置での再帰呼び出しは禁止されています。

(?<name>a|\g<name>b)   => error
(?<name>a|b\g<name>c)  => OK

選択

縦棒 | によって2つの部分正規表現のどちらか一方にマッチすれば良い 部分正規表現を記述できます。

/\w(and|or)\w/.match("Feliformia") # => #<MatchData "form" 1:"or">
/\w(and|or)\w/.match("furandi")    # => #<MatchData "randi" 1:"and">
/\w(and|or)\w/.match("dissemblance") # => nil

このメタ文字は選択子(alternation operator)と呼ばれます。

アンカー

アンカーは幅0の文字列にマッチするメタ文字列です。 幅0とは文字と文字の間、文字列の先頭、文字列の末尾、 などを意味します。 ある特定の条件を満たす「位置」にマッチします。

# 文字列中の real にマッチする
/real/.match("surrealist") # => #<MatchData "real">
# 先頭に real とないとマッチしない
/\Areal/.match("surrealist") # => nil
# 単語境界がrealの前にないのでマッチしない
/\breal/.match("surrealist") # => nil

単語を成す文字、成さない文字の定義はエンコードによって 異なります。以下の例で「全角」括弧は EUC-JP では 単語を成す文字と見なされますが、UTF-8 では見なされません。 その結果、以下のような挙動をします。

# -*- coding:utf-8 -*-
# デフォルトは UTF-8
/foo\b/.match("あいうfoo%") # => #<MatchData "foo">
/\bfoo\b/.match("あいうfoo%") # => nil
/\bfoo\b/e.match("(foo)".encode("EUC-JP")) # => nil
/\bfoo\b/.match("(foo)") # => #<MatchData "foo">

Unicode の規格では、単語を成す文字を Word というプロパティで 定義しています。

先読み、後読み(lookahead, lookbehind)

ある位置から続く文字列が ある部分式にマッチするならばその位置にマッチする という正規表現を書くことができます。

「ある位置から続く文字列(先読み、lookahead)/ある位置の手前までの文字列(後読み、lookbehind)」 と「マッチする(肯定、positive)/マッチしない(否定、negative)」 の組み合わせで4つのパターンがあります。

# 以下の例では、後読みと先読みを使って <b> と
# </b> に挟まれているという条件を正規表現中に記述しつつ
# <b> </b> 自体にはマッチさせていない。
/(?<=<b>)\w+(?=<\/b>)/.match("Fortune favours the <b>bold</b>")
# => #<MatchData "bold">
# 以下は上の正規表現と同じものを表す
/<b>\K\w+(?=<\/b>)/.match("Fortune favours the <b>bold</b>")
# => #<MatchData "bold">

条件分岐

(?(cond)pat) もしくは (?(cond)truepat|falsepat) という 記法で条件分岐を記述できます。

(?(cond)pat) は cond が真の場合は部分式 pat が使われます。 (?(cond)truepat|falsepat) は cond が真の場合は部分式 truepat が使われ、 偽の場合には falsepat が使われます。

条件可能な条件として以下があります。

以下の例は

set var=val
print var

という2つの命令を持つコマンドにマッチするような正規表現です。

re = /\A(?:(set)|(print))\s+(\w+)(?(1)=(\d+))\z/
re.match("set x=32") # => #<MatchData "set x=32" 1:"set" 2:nil 3:"x" 4:"32">
re.match("print x") # => #<MatchData "print x" 1:nil 2:"print" 3:"x" 4:nil>
re.match("set y") # => nil

オプション

/pat/という正規表現の直後に以下のアルファベットを 置くことで、正規表現にオプションを指定することができます。

i, m, x のオプションは (?on:pat) もしくは (?on-off:pat) という記法で 部分正規表現にのみ適用することができます。on、offにはi,m,xのいずれか を置きます。onにはpatの中でのみ局所的に有効にしたいオプションを、offには 局所的に無効化したいオプションを指定します。

/a(?i:b)c/.match("aBc") # => #<MatchData "aBc">
/a(?i:b)c/.match("abc") # => #<MatchData "abc">

(?on) もしくは (?on-off) という形式を使うと、そこから後の 部分正規表現のみオプションを有効化することができます。

/a(?i)bc/.match("aBc") # => #<MatchData "aBc">
/a(?i)bc/.match("aBC") # => #<MatchData "aBC">
# かっこの中で(?i)を指定すると、そのかっこの終わりまで有効
/a(?:(?i)bc)d/.match("aBCd") # => #<MatchData "aBCd">
/a(?:(?i)bc)d/.match("aBCD") # => nil

オプションは Regexp.new の引数に指定することもできます。

Regexp.new("abc", Regexp::IGNORECASE)                     # => /abc/i
Regexp.new("abc", Regexp::MULTILINE)                      # => /abc/m
Regexp.new("abc # Comment", Regexp::EXTENDED)             # => /abc # Comment/x
Regexp.new("abc", Regexp::IGNORECASE | Regexp::MULTILINE) # => /abc/mi

2.0.0以降では、文字クラスの挙動を変更するための d,a,u というオプションを (?on:pat)もしくは(?on)の形で指定することができます。(?on-off:pat), (?on-off) という形式を用いる場合はonの部分にのみ用いることができます(offはできません)。

d,a,u のオプションは正規表現直後に置く方式では指定ができません。

エンコーディング

通常、正規表現のエンコーディングはソースコードエンコーディングと 同じであると見なされます。 ただし正規表現が ascii 互換の文字しか含まない場合は エンコーディングは US-ASCII になります。

以下のオプションで変更することができます。

正規表現オブジェクトのエンコーディングは Regexp#encoding で 取得できます。

# -*- coding:utf-8 -*-
/あいう/.encoding # => #<Encoding:UTF-8>
/abc/.encoding # => #<Encoding:US-ASCII>
/abc/u.encoding # => #<Encoding:UTF-8>

正規表現のエンコーディングと文字列のエンコーディングが非互換で ある場合、Encoding::CompatibilityError が発生します。

エンコーディングについては 多言語化 も参考にしてください。

Regexp#fixed_encoding? で正規表現のエンコーディングが 「固定」さているかどうかを調べることができます。 これが真である場合には文字列とのエンコーディングが一致していないと マッチ時に例外が発生します。 これが偽である場合にはASCII互換な文字列であればマッチの判定をさせる ことができます。Regexp.newRegexp::FIXEDENCODING を 指定することで明示的に指定することが可能です。

# -*- coding:utf-8 -*-
/あいう/.fixed_encoding? # => true
/abc/.fixed_encoding? # => false
/abc/e.fixed_encoding? # => true
/abc/ =~ "あいう" # => nil
/abc/e =~ "あいう"
# ~> -:6:in `<main>': incompatible encoding regexp match (EUC-JP regexp with UTF-8 string) (Encoding::CompatibilityError)

コメント

(?#comment here) という記法で正規表現内にコメントを書くことができます。 この記法はフリーフォーマットモードでは使えません。 かわりに # で行末までがコメントになります。

フリーフォーマットモード

上に説明している x オプションを使うと空白を無視するようになります。 これをフリーフォマットモード(free format mode, free spacing modeとも) と呼びます。

フリーフォーマットモードでは # から行末まではコメント扱いされます。

float_pat = /\A
  \d+ # 整数部
  (\. # 小数点
    \d+ # 小数部
  )?  # 小数点 + 小数部 はなくともよい
\z/x
float_pat.match("3.14") # => #<MatchData "3.14" 1:".14">

空白を表現したい場合はエスケープをしてください。

/x y/x.match("x y") # => nil
/x\ y/x.match("x y") # => #<MatchData "x y">

\s や \p{Space} のような文字クラスを使うのが良い場合も多いでしょう。

非包含オペレータ (absence operator) (実験的)

(?~式) という記法で、式にマッチする文字列を含まない任意の文字列にマッチします。 (Ruby 2.4.1 で更新された Onigmo に含まれる機能のため、Ruby 2.4.0 では使えません。)

例えば (?~abc) は "", "ab", "aab", "abb", "ccdd" などにはマッチしますが、 "abc", "aabc", "ccabcdd" などにはマッチしません。

/\/\*(?~\*\/)\*\// は C スタイルのコメントにマッチします。 例えば "/**/", "/* foo bar */" など。

一覧

Rubyで利用可能なメタ文字、メタ文字列の一覧です。

文字クラス

特別な意味を持つ文字列

繰り返し

キャプチャ & グループ化

部分式呼び出し

選択子

アンカー

条件

オプション

コメント

非包含オペレータ

特殊変数

パターンマッチしたときに、以下の特殊変数にマッチの情報をセットします。

これらの変数はスレッドローカルかつメソッドでローカルな変数です。

参考文献