Xrの構文

Xrは正規表現を構築する領域特化言語です。 普通、 Xr メソッドを使います。 このメソッドはブロックを受け付け、その中で表現します。

構文の原則はいくつかあります。

まず、記号での表現と英語の単語があるとき、前者を優先します。 単語だと、利用者が使いたいものと衝突してしまうのではないか、という懸念からです。 これを、記号優先の原則とします。

次に、ある意味を表す記法は、基本的に1つ提供します。 様々には用意しません。 これは、既存の記法で席が埋まってしまい、将来、新しく意味を定義できなくなることを防ぐためです。 これを、単一記法の原則とします。

3つ目に、対の意味を持たせたい記法でも、一般に対とされる記号を使うとは限りません。

Xr により作成された正規表現は、できるだけ、評価の回数が少なくなるようにしてください。 理想的には、トップレベルの定数として定義し、1度だけ評価することです。 Xr は特に効率を意識していない実装であるため、毎回、表現を構築すると、時間が掛かります。

便覧

Xr のブロック内に何らかの直値があると、それを記法として解釈しようとします。

正規表現はその表現自体です。

Xr { /a/ }

文字列そのままは、それ自体の正規表現です。 つまり、正規表現で使われる、特殊な文字は効果がありません。 額面通りの文字列にするため、ブロックが文字列に評価されたときは、正規表現のエスケープを施します。

Xr { "何らかの文字列" }

しかし、最後の式だけが使われることに注意してください。

Xr { "これは無視される"; "これは使われる" }

配列は、要素を順番に連結したものです。

Xr { ["何らかの", "文字列"] }

seq (sequence) というメソッドを提供することも考えました。 例えば、Xr { seq "何らかの", "文字列" }のようになります。 また、空であれば単にXr { seq }です。 しかしこれは記号優先の原則により、取り下げました。

また、&を2項演算子にすることも考えました。 しかしこれは、単一記法の原則により、取り下げました。

Emacs Lispのrxパッケージ(以下 rx.el とします)には、 :and があります。

特定のシンボルは記法の中に書けます。

:not_newline は改行でない任意の1文字です。

Xr { :not_newline }

以降のシンボルの例は省略します。

nonl の追加は、単一記法の原則により行いません。 rx.el では not-newline があります。

:anychar は任意の1文字です。 anything の追加は、単一記法の原則により行いません。 rx.el では anychar があります。

alpha, alnum, digit, xdigit, cntrl, blank, space, lower, upper, graph, print, punct, word, ascii は文字クラスです。 rx.el にも同名のものがあります。

ゼロ幅断定として、 line_start, line_end, string_start, string_end, word_boundary があります。 rx.el には line-start, line-end, string-start, string-end, word-boundary があります。

文字集合は any で表現されます。

Xr { any 'ab' }
Xr { any 'a', 'b' }

含まれる文字はエスケープされるのでお気を付けください。 以下では、ハイフンを特別な意味に解釈しません。

Xr { any 'a-b' }

範囲も使えます。

Xr { any 'a'..'c' }

charin は、統一記号の原則から取り下げました。 Set も考えられますが、逆に指定した文字集合以外の場合を考えて取り下げました。

rx.el には any があります。 ただし、そちらでは-を範囲として解釈します。

除外する文字集合は except で表します。

Xr { except 'a' }

rx.el では not があります。

グループは group で囲みます。

Xr { group { 'a' } }

また、グループ名を付けられます。

Xr { group(:b) { 'b' } }

後方参照は backref です。

Xr { [group { 'a' }, backref(1)] }
Xr { [group(:b) { 'a' }, backref(:b)] }

選択

選択は|で表します。

Xr { _ | 'a' | 'b' }

_ ||で連結するためのおまじないと見れます。 空の選択は、合致不能を意味するのですが、それについては後述します。

choice を使うことも考えられましたが、記号優先の原則により、取り下げました。

rx.el には or があります。

合致不能は unmatchable です。

Xr { unmatchable }

choice があれば、Xr { choice }と書けますが、意図が伝わりにくそうです。 _! という記号も考えましたが、そこまで直感的でないように思われました。 そもそも、合致不能が頻用されるとは思えなかったため、記号への割り当てはしていません。

1回か0回

1回か0回合致するには、_?とします。 対象のパターンは位置引数に渡します。

Xr { _? 'a' }

zero_or_oneoptionalopt も考えましたが、記号優先の原則により取り下げました。

最小合致で1回か0回合致するには、さらに_?のブロックで囲みます。

Xr { _? { _? 'a' } }

最小合致の記法は提供していますが、最大合致の記法は提供していません。 maximum_match を提供することも考えています。

0回以上

0回以上の繰り返しは_ *を使います。

Xr { _ * 'a' }

zero_or_more は記号優先の原則により取り下げました。

rx.el では0+があります。

最小合致の0回以上の繰り返しは、_? *とします。

Xr { _? * 'a' }

minimal_match も考えましたが、記号優先の原則により取り下げました。

1回以上

1回以上の繰り返しは_ +を使います。

Xr { _ + 'a' }

one_or_more は記号優先の原則により取り下げました。

rx.el では1+があります。

最小合致の1回以上の繰り返しは、_? +とします。

Xr { _? + 'a' }

指定回数

指定回数の繰り返しは_ 自然数, ...です。

Xr { _ 3, 'a' }

repeat は記号優先の原則により取り下げました。 _自然数 = は、式を返すのでうまくいきません。

rx.el には= 自然数**があります。

回数の上限も指定できます。

Xr { _ 3..5, 'a' }

Xr { _ 3, 5, 'a' }も考えられましたが、単一記法の原則により取り下げました。

下限を指定することもできます。

Xr { _ 3.., 'a' }

or_more は記号優先の原則により取り下げました。

rx.el には>=があります。

上限を指定することもできます。

Xr { _ (..3), 'a' }

実装予定の記法

rx.elintersection は、文字集合の共通部分に合致するパターンです。 また、構文と分類がいろいろあります。 word-start は単語の始めです。 word-end は単語の終わりです。 symbol-start はシンボルの始めです。 symbol-end はシンボルの終わりです。