ruby-reference-manual:3764
From: Kazuhiro NISHIYAMA <zn@m...>
Date: Mon, 08 Jul 2013 22:51:03 +0900
Subject: [ruby-reference-manual:3764] Re: rurema/doctree@ad88ff3 [master] Renew regexp
西山和広です。 しっかり書かれていて、ざっと読むだけでも大変でした。 気付いた点をメモしたので ML に投げておきます。 At Sun, 07 Jul 2013 15:03:19 +0900, Ippei Obayashi wrote: > +=== 任意の1文字 > +メタ文字 . は改行を除く任意の1文字にマッチします。 > + > +ただし、オプション m によって改行にもマッチするようになります。 例があると良いかも。 > +文字クラスでは、否定(^)範囲(-)共通部分(&&)列挙(並べる)という > +演算が可能ですが、これらは - > (列挙) > && > ^ という順の結合強度を持ちます 文字クラスの中での結合強度とか知らなかったので勉強になりました。 > +文字クラス内の3つのメタ文字を通常の文字の意味で使用したい場合には、 > +\ によってエスケープ する必要があります。 & は単独ならエスケープ不要ですが、3つのメタ文字というのは? 文字クラスの中では "]" もエスケープが必要になるということも 書いておくと良さそうです。 > +==== 文字クラスの略記法 > +良く使われる文字クラスには省略記法が存在します。 > + * \w 単語構成文字 [a-zA-Z0-9_] > + * \W 非単語構成文字 [^a-zA-Z0-9_] > + * \s 空白文字 [ \t\r\n\f] > + * \S 非空白文字 [^ \t\r\n\f] > + * \d 10進数字 [0-9] > + * \D 非10進数字 [^0-9] > + * \h 16進数字 [0-9a-fA-F] > + * \H 非16進数字 [^0-9a-fA-F] > +これらの「空白」「数字」などは 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 http://slide.rabbit-shocker.org/authors/znz/ruby200-regexp/ にちょっと書いたのですが、このあたりは Onigmo だと (?a) (?d) (?u) で意味が変わるようです。 > +#@since 2.0.0 > +=== 特別な文字列に対するマッチ > +文字列の中には、CR LF のように、複数の文字一続きで1つの意味を表す > +ようなものが存在します。そのような文字列にマッチするような > +メタ文字列として以下が存在します。 > + * \R 改行 (?>\x0D\x0A|[\x0A-\x0D\x{85}\x{2028}\x{2029}]) Not Unicode の場合の記述もあると良さそうです。それから [\x0A-\x0D] なので垂直タブ(\v) などにもマッチするというのを ちょっと書いておくと良さそうです。 > + * \X Unicode 結合文字シーケンス (eXtended grapheme cluster) (?>\P{M}\p{M}*) \X はちょっと例があると良さそうです。 > +#@end > +==== 絶対最大量指定子(possesive qualifier) possesive → possessive > +アトミックグループを用いることで同じことができます。 アトミックグループ → アトミックグループ (?>subexp) のように例を付けておくとわかりやすくなりそうです。 > + # 4. \g<paran> で名前付きキャプチャ <paren> にマッチしようとする \g<paran> → \g<paren> > + * \b 単語境界にマッチします。 > + 単語を成す文字と単語を成さない文字の間にマッチします。 > + 文字列の先頭の文字が単語成す文字であれば、文字列の先頭 > + の位置にマッチします。 > + * \B 非単語境界にマッチします。 > + \bでマッチしない位置にマッチします。 > + > + # 文字列中の 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 というプロパティで > +定義しています。 Onigmo だと \b も (?a) (?d) (?u) の影響を受けます。 > +「ある位置から続く文字列(先読み、lookahead)/ある位置の手前までの文字列(後読み、lookbehind)」 > +と「マッチする(肯定、positive)/マッチしない(否定、negativge)」 negativge → negative > +の組み合わせで4つのパターンがあります。 > + * (?=pat) 肯定先読み(positive lookahead) > + * (?!pat) 否定先読み(negative lookahead) > + * (?<=pat) 肯定後読み(positive lookbehind) > + * (?<!pat) 否定後読み(negative lookbehind) > + * \K 後読みの別表記、このメタ文字列の手前までを後読みします。 > + つまり /pat1\Kpat2/ は /(?<=pat1)pat2/ と同様の意味となります。 > + > + # 以下の例では、後読みと先読みを使って <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"> \K は since 2.0.0 だと思います。 > +=== フリーフォーマットモード > +上に説明している x オプションを使うと空白を無視するようになります。 > +これをフリーフォマットモード(free format mode, free spaceing modeとも) > +と呼びます。 spaceing → spacing > + * {n} ちょうとn回(nは数字) (greedy) > + * {n}? ちょうとn回(nは数字) (reluctant) ちょうと → ちょうど > + * *+ 0回以上 (possesive) > + * ++ 1回以上 (possesive) > + * ?+ 0回もしくは1回 (possesive) possesive → possessive > + * \K 左側を肯定後読み ここも since 2.0.0 他に since 2.0.0 として、 (?a) (?d) (?u) がない。 それから Unicode blocks のサポートが since 2.0.0 の 機能として増えているのを http://slide.rabbit-shocker.org/authors/znz/ruby200-regexp/ には書いたのを思い出しました。 > + * [[m:$~]] 最後にマッチしたときの情報( 括弧が中途半端なのは何か書きかけ? > + * Ruby の tarball に含まれている doc/re.rdoc trunk だと doc/regexp.rdoc になっているようです。 -- |ZnZ(ゼット エヌ ゼット) |西山和広(Kazuhiro NISHIYAMA) -- ML: ruby-reference-manual@m... 使い方: http://QuickML.com/