Morilib ReiはJavaScriptの正規表現を補強するライブラリです。
Morilib Reiは以下のような特徴を持ちます。

  • JavaScriptオブジェクトによる正規表現の構築

  • Javaのようなマッチャクラス

使用方法

ブラウザ

ブラウザで使用するにはscriptタグでロードします。

<script src="rei.js"></script>

node.js

node.jsで使用するにはnpmよりパッケージをダウンロードします。

$ npm install morilib-rei

その後、使用するアプリケーションでmorilib-reiをrequireします。

var Re = require("morilib-rei");

JavaScriptオブジェクトによる正規表現の構築

JavaScriptにより正規表現を構築できます。このことにより正規表現の意味がわかりやすくなります。

Re.iまたはRe.build

Morilib Reiにより正規表現を構築するにはRe.iまたはRe.build関数を使用します。

var regex = Re.i([ "www.", "morilib.", "net/" ]);
var regex = Re.bulid([ "www.", "morilib.", "net/" ]);

単純な文字列

文字列リテラルは単純な文字列にマッチします。文字列中の正規表現メタキャラクタはエスケープされます。

var regex = Re.i("www.morilib.net/");
console.log(regex.test("www.morilib.net/"));   // true
console.log(regex.test("wwwwmorilib_net/"));   // false

パターンの連接

パターンの連接には連接したいパターンを配列の要素にします。

var regex = Re.i([ "www.", "morilib.", "net/" ]);
console.log(regex.test("www.morilib.net/"));   // true
console.log(regex.test("wwwwmorilib_net/"));   // false

繰り返し

パターンの繰り返しには以下のようなプロパティを持つオブジェクトを記述します。

プロパティ名 内容

oneOrMore

1回以上の繰り返し

zeroOrMore

0回以上の繰り返し

maybe

0回または1回の出現

repeat

n回からm回の繰り返し

oneOrMoreNonGreedy

1回以上の繰り返し(非欲張り)

zeroOrMoreNonGreedy

0回以上の繰り返し(非欲張り)

maybeNonGreedy

0回または1回の出現(非欲張り)

repeatNonGreedy

n回からm回の繰り返し(非欲張り)

1回以上の繰り返しは以下のように記述します。

var regex = Re.i({ "oneOrMore": "a" });
console.log(regex.test("aaaaa"));  // true

n回からm回の繰り返しは以下のように記述します。

var regex = Re.i({
  "repeat": {
    "from": 2,
    "to": 5,
    "pattern": "a"
  }
});
console.log(regex.test("aaa"));  // true

プロパティ名には別名があります。例えば、oneOrMoreの代わりにrepeatOneOrMoreと書いても問題ありません。
プロパティ名は大文字小文字を区別しません。
詳しくは「記法」の章を参照してください。

選択

選択はorを使用します。プロパティの要素には配列を指定します。

var regex = Re.i({ "or": [ "765", "876", "346", "283" ] });
console.log(regex.test("765"));  // true
console.log(regex.test("961"));  // false

文字セット

文字セットはcharsetを使用します。プロパティの要素には定義済み文字セットまたはrangeを指定します。
補文字セットはcomplementaryCharsetを使用します。
定義済み文字セットの詳細については「定義済み文字セット」の章を参照してください。

var regex = Re.i({ "charset": "digit" });
console.log(regex.test("2"));  // true
var regex = Re.i({
  "charset": {
    "range": {
      "from": "a",
      "to": "z"
    }
  }
});
console.log(regex.test("a"));  // true

キャプチャ

キャプチャはcaptureを使用します。
後方参照にはreferを使用します。referの要素にはキャプチャの番号を指定します。

var regex = Re.i([
  {
    "capture": {
      "charset": "all"
    }
  },
  { "refer": 1 }
]);
console.log(regex.test("aa"));  // true

名前付きキャプチャ

キャプチャには名前をつけることができます。
名前付きキャプチャを使用するにはcaptureプロパティの要素に"name"を含むオブジェクトを指定します。

var regex = Re.i([
  {
    "capture": {
      "name": "char",
      "pattern": {
        "charset": "all"
      }
    }
  },
  { "refer": "char" }
]);
console.log(regex.test("aa"));  // true

生の正規表現

生の正規表現を埋め込むことができます。正規表現の埋め込みにはrawを指定します。
生の正規表現中のキャプチャの括弧は認識されます。

// capture of raw regex is considered
var regex = Re.i([
  { "raw": "<([^>]+)>" },
  {
    "capture": {
      "name": "body",
      "pattern": {
        "oneOrMoreNonGreedy": {
          "charset": "all"
        }
      }
    }
  },
  { "raw": "</[^>]+>" }
]);
// { 0: "<a>index.html</a>", 1: "a", 2: "index.html", body: "index.html" }
console.log(regex.execWithName("<a>index.html</a>"));

Unicodeプロパティ

Unicodeプロパティを使用するにはJavaScriptオブジェクトのunicodeプロパティを使用します。
Unicodeプロパティ名の前にはIsをつけることもできます。
Unicodeプロパティの種類により以下のヘッダがつきます。

内容 ヘッダ

カテゴリ

(なし)

Math Symbol

双方向カテゴリ

Bidi_Class:

Bidi_Class:Left to Right

ブロック

Block:またはBlk=またはIn

Block: Basic Latin

用字

Script=またはsc=またはScript:

Script=Greek

Unicodeプロパティの単語の区切りにはスペース、アンダースコア(_)、ハイフン(-)を使用することができます。

// expands Unicode Property Letter to a character set
var regex = Re.i([
  { "anchor": "begin" },
  {
    "oneOrMore": {
      "unicode": "Letter"
    }
  },
  { "anchor": "end" }
]);
console.log(regex.test("Reiは正規表現のライブラリです"));  // true

定義済みシーケンス

Morilib Reiにはいくつかの定義済みシーケンスが定義されています。
定義済みシーケンスを使用するにはsequenceプロパティを使用します。
定義済みシーケンスの詳細は「定義済みシーケンス」を参照してください。

var regex = Re.i([
  { "anchor": "begin" },
  { "sequence": "real" },
  { "anchor": "end" }
]);
console.log(regex.test("3.46e+27"));  // true

Javaライクなマッチャクラス

Morilib Reiでは連続したマッチを実現するためにマッチャクラスを用意しています。
マッチャクラスの生成にはRe.i関数により生成されたクラスのmatcherメソッドを使用します。

var matcher = Re.i({ "unicode": "Letter" }).matcher("Rei");

マッチャクラスは下記のメソッドを持ちます。
下記のメソッドにおいて、マッチの開始位置は前回マッチした最後の位置となります。
マッチが失敗したときはマッチの位置は変わりません。

メソッド 内容

find

マッチの開始位置からパターンを検索します

lookingAt

マッチの開始位置から始まるパターンを検索します

matches

マッチの開始位置から始まり、文字列の最後で終わるパターンを検索します

usePattern

マッチに使用するパターンを変更します。マッチの開始位置は変わりません

usePatternを使用することでパターンを変えながらマッチさせることができます。
usePatternを使用してLispで使用されるS式を解析する例を以下に挙げます。

function parseS(aString) {
    var undef = void 0,
        isDot = false,
        stack = [],
        matching,
        matcher;
    function pushStack(anObject) {
        var stackTop = stack[stack.length - 1];
        if(isDot) {
            stackTop.now.cdr = anObject;
            isDot = false;
        } else {
            if(!stackTop.now) {
                stackTop.now = stackTop.start;
            } else {
                stackTop.now = stackTop.now.cdr;
            }
            stackTop.now.car = anObject;
            stackTop.now.cdr = {};
        }
    }

    matcher = Re.i(/$/g).matcher(aString);
    while(!matcher.usePattern(Re.i({ "anchor": "end" }, "global")).lookingAt()) {
        if(matcher.usePattern(Re.i("(", "global")).lookingAt()) {
            stack.push({
                start: {},
                now: null
            });
            matching = undef;
        } else if(matcher.usePattern(Re.i(")", "global")).lookingAt()) {
            matching = stack.pop().start;
        } else if(matcher.usePattern(Re.i([ ".", { "lookahead": { "charset": "space" } } ], "global")).lookingAt()) {
            if(isDot || !stack[stack.length - 1].now) {
                throw new Error("invalid dot");
            }
            matching = undef;
            isDot = true;
        } else if(matcher.usePattern(Re.i({ "sequence": "real" }, "global")).lookingAt()) {
            matching = parseFloat(matcher.group[0]);
        } else if(matcher.usePattern(Re.i({ "oneOrMore": { "charset": "nonspace" } }, "global")).lookingAt()) {
            matching = matcher.group[0];
        }

        if(matching === undef) {
            // do nothing
        } else if(stack.length === 0) {
            return matching;
        } else {
            pushStack(matching);
        }
        matcher.usePattern(Re.i({ "zeroOrMore": { "charset": "space" } }, "global")).lookingAt();
    }
    return undef;
}

記法

zeroOrMore

alias: repeatZeroOrMore

Format

{
  "zeroOrMore": <pattern>
}

Example

{
  "zeroOrMore": "a"
}

correspond regular expression: a*
matches aaaaa for input aaaaab
matches <empty> for input b

Description

与えられたパターンを0回以上繰り返します。

oneOrMore

alias: repeatOneOrMore

Format

{
  "oneOrMore": <pattern>
}

Example

{
  "oneOrMore": "a"
}

correspond regular expression: a+
matches aaaaa for input aaaaab
no match for input b

Description

与えられたパターンを1回以上繰り返します。

maybe

alias: option, optional

Format

{
  "maybe": <pattern>
}

Example

{
  "maybe": "a"
}

correspond regular expression: a?
matches a for input aaaaab
matches <empty> for input b

Description

与えられたパターンを0回または1回繰り返します。

repeat

Format

{
  "repeat": {
    "from": <number>,
    "to": <number>,
    "pattern": <pattern>
  }
}

Example

{
  "repeat": {
    "from": 1,
    "to": 3,
    "pattern": "a"
  }
}

correspond regular expression: a{1,3}
matches aaa for input aaaaab
matches a for input ab

Description

与えられたパターンを少なくとも"from"回、多くとも"to"回繰り返します。
"from"が指定されなかったときは0になります。 "to"が指定されなかったときは繰り返しの上限はなくなります。

zeroOrMoreNonGreedy

alias: repeatZeroOrMoreNonGreedy, repeatZeroOrMoreNotGreedy, zeroOrMoreNotGreedy

Format

{
  "zeroOrMoreNonGreedy": <pattern>
}

Example

[
  {
    "zeroOrMoreNonGreedy": {
      "charset": "exceptNewline"
    }
  },
  "-"
]

correspond regular expression: .*?-
matches aaaaa for input aaaaa-a-

Description

与えられたパターンを0回以上繰り返します。最小の範囲にマッチします。
上記の例ではaaaaa-a-はaaaaaにマッチします。 もし、zeroOrMoreを代わりに使用したときはaaaaa-aにマッチします。

oneOrMoreNonGreedy

alias: repeatOneOrMoreNonGreedy, repeatOneOrMoreNotGreedy, oneOrMoreNotGreedy

Format

{
  "oneOrMoreNonGreedy": <pattern>
}

Example

[
  {
    "oneOrMoreNonGreedy": {
      "charset": "exceptNewline"
    }
  },
  "-"
]

correspond regular expression: .+?-
matches aaaaa for input aaaaa-a-

Description

与えられたパターンを1回以上繰り返します。最小の範囲にマッチします。
上記の例ではaaaaa-a-はaaaaaにマッチします。 もし、oneOrMoreを代わりに使用したときはaaaaa-aにマッチします。

maybeNonGreedy

alias: optionalNonGreedy, optionalNotGreedy, optionNonGreedy, optionNotGreedy, maybeNotGreedy

Format

{
  "maybeNonGreedy": <pattern>
}

Example

[
  {
    "maybeNonGreedy": {
      "charset": "exceptNewline"
    }
  },
  "-"
]

correspond regular expression: .??-
matches <empty> for input — 

Description

与えられたパターンを0回または1回繰り返します。最小の範囲にマッチします。
上記の例では—​は空文字列にマッチします。 もし、maybeを代わりに使用したときは-にマッチします。

repeatNonGreedy

alias: repeatNotGreedy

Format

{
  "repeatNonGreedy": {
    "from": <number>,
    "to": <number>,
    "pattern": <pattern>
  }
}

Example

[
  {
    "repeat": {
      "from": 1,
      "to": 10,
      "pattern": {
        "charset": "exceptNewline"
      }
    }
  },
  "-"
]

correspond regular expression: .{1,10}?-
matches aaaaa for input aaaaa-a-

Description

与えられたパターンを少なくとも"from"回、多くとも"to"回繰り返します。最小の範囲にマッチします。
"from"が指定されなかったときは0になります。 "to"が指定されなかったときは繰り返しの上限はなくなります。 上記の例ではaaaaa-a-はaaaaaにマッチします。 もし、repeatを代わりに使用したときはaaaaa-aにマッチします。

or

alias: alter, alternate, alternation, alternative

Format

{
  "or": [ list of alternation ]
}

Example

{
  "or": [ "765", "346", "283" ]
}

correspond regular expression: 765|346|283
matches 765 for input 765pro

Description

リスト内のパターンのいずれかにマッチします。

capture

Format

{
  "capture": <pattern>
}
{
  "capture": {
    "name": <name>
    "pattern": <pattern>
  }
}

Example

{
  "capture": {
    "zeroOrMore": "a"
  }
}

correspond regular expression: "(a*)"

Description

与えられたパターンにマッチし、結果を保存します。
値に"name"のプロパティを含むオブジェクトが与えられたときは結果に名前がつけられます。
名前付きキャプチャはMorilib ReiのAPIを通じて使用することができます。
名前付きキャプチャにも通常と同様のキャプチャ番号が採番されます。

raw

alias: regex, regexp

Format

{
  "raw": <raw regex>
}

Example

{
  "raw": "a+b"
}

correspond regular expression: a+b

Description

生の正規表現を埋め込みます。

charset

alias: characterSet

Format

{
  "charset": <name of character set>
}

Example

{
  "charset": "all"
}

correspond regular expression: [\s\S]

Description

与えられた文字セット内の文字にマッチします。

complementCharset

alias: complementSet, complementaryCharset, complementarySet, complementCharacterSet, complementaryCharacterSet

Format

{
  "complementCharset": <name of character set>
}

Example

{
  "complementCharset": "digit"
}

correspond regular expression: [^\d]

Description

与えられた文字セットにない文字にマッチします。

anchor

alias: bound

Format

{
  "anchor": <name of anchor>
}

Example

[
  {
    "anchor": "beginOfLine"
  },
  "abc"
]

correspond regular expression: ^abc
matches abc for input abc
no match for input dabc

Description

境界にマッチします。以下のものが名称として使用できます。

begin, start, beginOfLine startOfLine

行または入力の最初にマッチする

end, endOfLine

行または入力の最後にマッチする

word, wordBound, wordBoundary

単語の境界にマッチする

nonWord, nonWordBound, nonWordBoundary, notWord, notWordBound, notWordBoundary

非単語の境界にマッチする

charCode

alias: characterCode

Format

{
  "charCode": <character code>
}

Example

{
  "charCode": 41
}

correspond regular expression: \u0041

Description

UTF-16文字コードで与えられた文字にマッチします。

lookahead

alias: positiveLookahead, lookaheadAssertion, positiveLookaheadAssertion

Format

{
  "lookahead": <pattern>
}

Example

[
  "765",
  {
    "lookahead": "pro"
  }
]

correspond regular expression: 765(?=pro)
matches 765 for input 765pro
no match for input 765

Description

与えられたパターンにマッチしますが、入力は消費しません。

negativeLookahead

alias: negativeLookaheadAssertion

Format

{
  "negativeLookahead": <pattern>
}

Example

[
  "765",
  {
    "negativeLookahead": "?"
  }
]

correspond regular expression: 765(?!\?)
matches 765 for input 765!
no match for input 765?

Description

与えられたパターンにマッチしないときマッチしますが、入力は消費しません。

unicode

alias: unicodeProperty

Format

{
  "unicode": <unicode property>
}

Example

{
  "unicode": "L"
}

correspond regular expression: \p{L}

Description

与えられたUnicodeプロパティにある文字にマッチします。

complementUnicode

alias: complementaryUnicode, complementUnicodeProperty, complementaryUnicodeProperty

Format

{
  "complementUnicode": <unicode property>
}

Example

{
  "complementUnicode": "L"
}

correspond regular expression: \P{L}

Description

与えられたUnicodeプロパティにない文字にマッチします。

sequence

alias: seq

Format

{
  "sequence": <name of sequence>
}

Example

{
  "sequence": "real"
}

Description

与えられた名称の定義済みパターンにマッチします。

文字セット記法

range

Format

{
  "range": {
    "from": <charcter>
    "to": <charcter>
  }
}

Example

{
  "range": {
    "from": "a",
    "to": "z"
  }
}

Description

与えられた"from"プロパティから"to"プロパティに含まれる文字にマッチします。

unicode

alias: unicodeProperty

Format

{
  "unicode": <unicode property>
}

Example

{
  "unicode": "L"
}

Description

与えられたUnicodeプロパティにある文字にマッチします。

complementUnicode

alias: complementaryUnicode, complementUnicodeProperty, complementaryUnicodeProperty

Format

{
  "complementUnicode": <unicode property>
}

Example

{
  "complementUnicode": "L"
}

Description

与えられたUnicodeプロパティにない文字にマッチします。

定義済み文字セット

all

Description

全ての文字にマッチします。

digit

Description

数字にマッチします。

nonDigit

alias: notDigit

Description

数字でない文字にマッチします。

word

Description

単語を構成する文字にマッチします。

nonWord

alias: notWord

Description

単語を構成しない文字にマッチします。

space

alias: whitespace

Description

空白文字にマッチします。

nonSpace

alias: notSpace, nonWhitespace, notWhitespace

Description

空白文字でない文字にマッチします。

tab

Description

タブ文字にマッチします。

carriageReturn

alias: cr

Description

CR文字にマッチします。

lineFeed

alias: lf

Description

行送り文字にマッチします。

verticalTab

alias: vt

Description

垂直タブ文字にマッチします。

formFeed

alias: ff

Description

form feed文字にマッチします。

backspace

alias: bs

Description

バックスペース文字にマッチします。

定義済みシーケンス

all

Description

全ての文字にマッチします。

exceptNewline

alias: allExceptNewline

Description

改行文字を除く全ての文字にマッチします。

newline

alias: nl, br

Description

改行を表すシーケンスに一致します。CRLFのようなシーケンスにもマッチします。

real

alias: float, realNumber, floatNumber, realNumberWithSign, floatNumberWithSign

Description

浮動小数点数にマッチします。符号にもマッチします。

realWithoutSign

alias: floatWithoutSign, realNumberWithoutSign, floatNumberWithoutSign

Description

浮動小数点数にマッチします。符号にはマッチしません。

API

Rei.execWithName

Parameter

Name Description

aString

マッチさせる文字列

Return

キャプチャされた文字列

Description

与えらた文字列をパターンにマッチさせます。

Example Code

var result = Re.i([
  {
    "capture": {
       "name": "a",
       "pattern": {
         "oneOrMoreNonGreedy": {
           "charset": "all"
         }
       }
    }
  },
  ";"
]).execWithName("abc;");
console.log(result.a);  // output "abc"

Rei.matcher

Parameter

Name Description

aString

マッチさせる文字列

Return

生成されたマッチャ

Description

マッチャを生成します。

Example Code

var matcher = Re.i([
  {
    "capture": {
       "name": "a",
       "pattern": {
         "oneOrMoreNonGreedy": {
           "charset": "all"
         }
       }
    }
  },
  ";"
]).matcher("abc;");

Rei.find

Return

マッチした結果

Description

パターンにマッチするシーケンスを探します。
戻り値はRegExp.exec()と同じです。

Example Code

var json = [
  {
    "capture": {
       "name": "a",
       "pattern": {
         "oneOrMoreNonGreedy": {
           "charset": "all"
         }
       }
    }
  },
  ";"
];
var matcher = Re.i(json).matches("@@@@@abc;@@@@@def;");
var result = matcher.find();
console.log(result.a);  // output abc
result = matcher.find();
console.log(result.a);  // output def

Rei.lookingAt

Return

マッチした結果

Description

パターンにマッチするシーケンスに最後にマッチした位置からマッチさせます。
マッチに失敗したときのマッチの最後位置は変わりません。
戻り値はRegExp.exec()と同じです。

Example Code

var json = [
  {
    "capture": {
       "name": "a",
       "pattern": {
         "oneOrMoreNonGreedy": {
           "charset": "all"
         }
       }
    }
  },
  ";"
];
var matcher = Re.i(json).matches("abc;@@@@@def;");
var result = matcher.lookingAt();
console.log(result.a);  // output abc
result = matcher.lookingAt();
console.log(result);  // output null

Rei.matches

Return

マッチした結果

Description

パターンにマッチするシーケンスに最後にマッチした位置からシーケンスの最後までマッチします。
マッチに失敗したときのマッチの最後位置は変わりません。
戻り値はRegExp.exec()と同じです。

Example Code

var json = [
  {
    "capture": {
       "name": "a",
       "pattern": {
         "oneOrMoreNonGreedy": {
           "charset": "all"
         }
       }
    }
  },
  ";"
];
var matcher = Re.i(json).matches("abc;");
var result = matcher.lookingAt();
console.log(result.a);  // output abc
matcher = Re.i(json).matches("@@@@abc;");
result = matcher.matches();
console.log(result);  // output null

Rei.usePattern

Parameter

Name Description

regexOrJson

RegExpオブジェクトまたはMorilib Reiで解釈できるJavaScriptオブジェクト

Return

このインスタンス

Description

マッチに使用するパターンを与えられたものに切り替えます。
マッチの最後位置は変わりません。

Example Code

var json1 = [
  {
    "capture": {
       "name": "a",
       "pattern": {
         "oneOrMoreNonGreedy": {
           "charset": "all"
         }
       }
    }
  },
  ";"
];
var json2 = {
  "capture": {
     "name": "a",
     "pattern": {
       "oneOrMoreNonGreedy": {
         "charset": "digit"
       }
     }
  }
};
var matcher = Re.i(json1).matches("@@@@@abc@@@@@a01a;");
var result = matcher.find();
console.log(result.a);  // output abc
matcher.usePattern(json2);
result = matcher.matches();
console.log(result);  // output 01