SRE
http://www.scsh.net/docu/post/sre.html
http://www.scsh.net/docu/html/man-Z-H-7.html
S-expression Regular Expression。正規表現のS式表記。
例えば、日付にマッチする正規表現を次のようにかくことができる。
(define date-sre (rx (seq (or "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec") (+ whitespace) (or ("123456789") (seq ("12") digit) "30" "31"))))
構文
Gauche の正規表現との対応関係は以下の通り。
SRE | Gauche |
(* re ...) | (?:re...)* |
該当なし | re*? |
該当なし | re*+ |
(+ re ...) | (?:re...)+ |
該当なし | re+? |
該当なし | re++ |
(? re ...) | (?:re...)? |
該当なし | re?? |
該当なし | re?+ |
(= n re ...) | (?:re...){n} |
(>= n re ...) | (?:re...){n,} |
該当なし | re{n,}? |
(** n m re ...) | (?:re...){n,m} |
該当なし | re{n,m}? |
(submatch re ...) | (re...) |
(uncase re ...) | (?i:re...) |
該当なし | (?-i:re...) |
(| pat1 pat2 ...), (or pat1 pat2 ...) | pat1|pat2|... |
(: pat1 pat2 ...), (seq pat1 pat2 ...) | pat1pat2... |
("abcd") | [abcd] |
(/"az" "AZ"), (/"azAZ"), (/ #\a #\z "AZ"), etc. | [a-zA-Z] |
any | . |
bos | ^ |
eos | $ |
bol | 行頭。該当なし(理由はGauche:regexp) |
eol | 行末。該当なし |
bow | 語の先頭。\b |
eol | 語の末尾。\b |
該当なし | \B |
alphabetic | [[:alpha:]] |
alphanumeric | [[:alnum:]] |
ascii | [\x00-\x0f] |
blank | [[:blank:]] |
control | [[:cntrl:]] |
graphic | [[:graph:]] |
hex-digit | [[:xdigit:]] |
lower-case | [[:lower:]] |
nonl | [^\n] |
numeric | \d |
printing | [[:print:]] |
punctuation | [[:punct:]] |
upper-case | [[:upper:]] |
whitespace | \s |
word | \w |
(~ numeric) | \D |
(~ whitespace) | \S |
(~ word) | \W |
該当なし | (?=re) |
該当なし | (?!re) |
該当なし | (?<=re) |
該当なし | (?<!re) |
該当なし | (?>re) |
該当なし | (?<name>re) |
該当なし | \n |
該当なし | \k<name> |
またさらに、文字クラス同士の集合演算をおこなうこともできる。
- (| <cset> ...)
文字クラスの和集合。ただし (|) = #[]
- (- <cset> ...)
文字クラスの差集合
- (& <cset> ...)
文字クラスの積集合
- (~ <cset> ...)
<cset> ... の和集合の補集合。(~ <cset> ...) = (~ (| <cset> ...))。 また、(~) = (~ (|)) = any
このとき、文字、長さ 1 の文字列もそれぞれ文字集合としてあつかわれる。
lexical case sensivity context
SRE 中の文字、文字列、文字集合は lexical case sensivity context にしたがって解釈される。lexical case sensivity context は w/case と w/nocase で切り替える(トップレベルの context は case sensitive)。
たとえば、
(w/nocase "abc" (* "FOO" (w/case "Bar")) ("aeiou"))
のような SRE は /[aA][bB][cC](?:[Ff][Oo][Oo]Bar)*[aeiouAEIOU]/ と同等の正規表現と解釈される。
lexical case sensivity context が影響をあたえるのは文字列 "foo"、 文字 #\a、文字集合 ("abc")、範囲指定による文字集合 (/"az") のみで、文字クラスの名前指定には影響しない。たとえば (w/nocase lower) は alpha と同等にはならない。また、後述の埋め込み SRE にも影響を与えない。
さらに、w/nocase と uncase は同等でないことにも注意。
(uncase (~ "a")) (w/nocase (~ "a"))
のようなふたつの SRE を比較すると、 uncase の方では、まず (~ "a") が [^a] と解釈される。これは A に マッチするので (uncase (~ "a")) は a にもマッチする。したがって、 (uncase (~ "a")) は結局すべての文字にマッチすることになる。
これに対して w/nocase の場合では、まず "a" が [aA] と解釈され、 (w/nocase (~ "a")) 全体は [^aA] と同等のものとして解釈される。
SRE の埋め込み
,<exp> のようにすると、SRE のなかに文字や文字列、文字集合、 正規表現をうめこむことができる。
例:
(rx (+ ,(if (zero? n) "white" "red")))
, をつかって埋め込んだ場合、展開された SRE にふくまれていたサブマッチ情報はすべてとりのぞかれる。
サブマッチ情報をのこしたまま埋め込みたい場合には ,@ をつかう。
例:
(define p (rx (submatch "b" (submatch "a")))) ; === (b(a)) (rx (submatch "c" ,p)) ; === (cba) (rx (submatch "c" ,@p)) ; === (c(b(a)))