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