基本は少ないけど、自分みたいな属性の人間には理解がきつい。でも、効果がかなり高いことを知ってしまったので、がんばろうと思います。
いろんなサイトを検索しましたが、下記のサイトがまとまっていたので、「まずは」見るものを絞って勉強しようと思います。
正規表現とは文字列のパターンを自分で見つけて、作ることです。(だと思っています。)
パターンを作るにあたって、大きく分けて次の4つの概念があります。(勝手に理解しています。)
- 文字
- 文字グループ
- 量指定
- 行頭・行末
ちなみにパターンマッチは、最初の一つに対して行われます。
正規表現 – JavaScript | MDN
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions
↓
- 文字クラス
文字クラス - JavaScript | MDN文字クラスは、文字や数字の区別など、文字の種類を区別します。 - 数量詞
数量詞 - JavaScript | MDN数量詞は、一致させる文字や式の数を示します。 - グループと範囲
グループと後方参照 - JavaScript | MDNグループは複数のパターンを全体としてグループ化し、グループをキャプチャすることで、正規表現パターンを使用して文字列と一致する場合に、追加の副一致情報を提供します。後方参照は、同じ正規表現で以前に捕捉したグループを参照します。 - 言明(行頭・行末のこと)
アサーション - JavaScript | MDNアサーションには、 行や単語の先頭・末尾を示す境界や、(先読み、後読み、条件式を含む)何らかの方法で照合が可能なことを示す、その他のパターンが含まれます。
1.文字
「.」
一部を除いてあらゆる1文字を表します。
一部とは、行末文字コードです。だからほとんどの1文字を「.」で表現できます。
「\d」
数字1文字を表します。0から9についてを表します。後述の文字グループの[0-9]と同じです。
「\D」
大文字になると、それ以外になります。というのは「\Dは数字以外の1文字」を表します。
[^0-9]と同じです。
「\w」
半角英数字とアンダースコアの1文字に該当します。[A-Za-z0-9]と同じです。
「\W」
ということは、大文字Wになったということは…「半角英数字とアンダースコア以外の1文字」を表します。[^A-Za-z0-9_]ということです。
「\s」
「スペース、タブ、改ページ、改行を含むホワイトスペース文字にマッチします。」ということです。
見えない文字ということでしょうか笑?
「\S」
ということは…そうです「ホワイトスペース以外の文字にマッチします。」
他は簡単にまとめます
正規表現 | 意味 |
---|---|
\t | タブ (U+0009) にマッチします。 |
\r | 復帰文字 (U+000D) にマッチします。 |
\n | 改行文字 (U+000A) にマッチします。 |
\v | 垂直タブ (U+000B) にマッチします。 |
Google検索「復帰文字」
Google検索「改行文字」
Google検索「垂直タブ」
こちらのサイトには続きの記載がありますが省略させていただきます。
2.量指定・繰り返し
最初に言っておきますが、「{}」から学んだほうが私みたいな属性の人間は入りやすいです。しかし、とりあえずサイトの順番に則ります。
文字の表現(\dとか)の右横に数を表す正規表現を記述します。
x*
xの0回以上の繰り返しにマッチします。xは無くてもいいということです。後述しますが、「{0,}」と同じ?
x+
xの1回以上の繰り返しにマッチします。xは{1,}に相当します。
x?
これ難しいぞ!
xの0回か1回にマッチします。存在有無ですかね?だから「?」なのでしょうか?
例えば /e?le?/ は “angel” の “el” や “angle” の “le”、あるいは “oslo” の “l” にマッチします。
にらめっこしてて、ひとつ気付いたけど、「/e?le?/」これって4パターンあるよね?
- /ele/
- /el/
- /le/
- /l/
間違ってる?そしたら例「angel」には上記の2つ目の「el」が該当します。2つ目の例「oslo」には、4つ目の「l」が該当します。
x?のもうひとつの機能
*、+、?、{} といった量指定子の直後に使用した場合、その量指定子をデフォルトとは逆の非貪欲 (non-greedy) (最短)マッチにします。デフォルトは欲張り (greedy)(最長)マッチです。
なんだ?なんだ?これも難しいぞ!よく読む、よく見る。
例「caaaaaaandy」
x = "caaaaaaandy" puts x.match(/a+/) puts x.match(/a+?/) puts x.match(/a{3}/) puts x.match(/a{3}?/)
やっぱり難しい…苦笑。これについては場数を踏んで都度学びます。
x{n}
回数指定。
x{n,}
n回以上の出現にマッチする。少なくともn回にマッチします。
x{n,m}
n回からm回までの出現にマッチします。少なくてもn回、多くてもm回の出現にマッチします。
補足1
x*?, x+?, x??, x{n}?, x{n,}?, x{n,m}?
既定では * や + といった数量詞は貪欲 (greedy) です。つまり、できる限り多くの文字列とマッチしようとします。数量詞の後にある ? 文字は非貪欲 (non-greedy) 数量詞をつくります: つまり、マッチが見つかるとすぐに停止します。
例えば、"some <foo> <bar> new </bar> </foo> thing" といった文字列が与えられたなら: /<.*>/ はおそらく "<foo> <bar> new </bar> </foo>" にマッチするでしょう /<.*?>/ はおそらく "<foo>" にマッチするでしょう
補足2
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Quantifiersからサンプル文字列を引用致します。
x = "I must be getting somewhere near the centre of the earth." puts x.match(/[\w ]+/) x = "I must be getting somewhere near the centre of the earth." puts x.match(/[\w ]+?/) x = "I must be getting somewhere near the centre of the earth." puts x.match(/[\w ]*?/)
勘違い
なんとなく感覚でわかってきた?
「最短条件が見つかると終了!」ってこと?
「文字列の左から走査します」ということも重要です。
なんとなく…。私はパターンマッチという言葉を理解していない?腑に落ちていない?のかもしれない。
「I must be getting」に対して、「/[\w ]+?/」を発動する。
※後日訂正。上記の例文は半角スペースを入れないでください。
- \wが当てはまる
- それが1回以上続く
- もし「?」がつかなければ終わりまでマッチする
- 「?」がついたので「1回以上」を最短の「1回」で止める
- 結果「I」だけのマッチになる
最初の文字が[\w ]だから空白がマッチしないからパターンマッチなしということではなく、「かつ」ではなく「または」なんだね。
正規表現は出来るだけ頑張ってマッチを探しに行ってくれている、ということである。
まだこれ「[\w ]+?」は自分では作れないな。
引用ページに記載の続きがありますが省略させていただきます。
3.グループ
x|y
xかyにマッチします。
[xyz]
文字集合というらしいです。[]の中のどれか1文字にマッチします。[xyz]だとxかyかzにマッチします。
ハイフンに注意です。文字と文字の間のハイフンは範囲を示します。ハイフンを文字としてマッチさせたい時は最初か最後に記述します。[-a-z]
[^xyz]
文字集合の否定と補集合です。
引用ページに記載の続きがありますが省略させていただきます。
4.行頭・行末
^行頭
^は、
入力の先頭にマッチします。
例えば /^A/ は “an A” の ‘A’ にはマッチしませんが、”An E” の ‘A’ にはマッチします。
$行末
$は、
入力の末尾にマッチします。
例えば /t$/ は “eater” の “t” にはマッチしませんが、”eat” の “t” にはマッチします。
補足
rubyの場合は他にもいろいろとあるようです。
http://doc.okkez.net/static/1.8.7/doc/spec=2fregexp.html