正規表現にオプションパーツを実装する方法について質問があります。古き良きテキストアドベンチャー入力の解析から例を取り上げました。これは私の仕事をかなりよく強調しています。これが私が何を求めているかを示す例です:
var exp = /^([a-z]+)(?:\s([a-z0-9\s]+)\s(on|with)\s([a-z\s]+))?$/i;
var strings = [
"look",
"take key",
"take the key",
"put key on table",
"put the key on the table",
"open the wooden door with the small rusty key"
];
for (var i=0; i < strings.length;i++) {
var match = exp.exec(strings[i]);
if (match) {
var verb = match[1];
var directObject = match[2];
var preposition = match[3];
var indirectObject = match[4];
console.log("String: " + strings[i]);
console.log(" Verb: " + verb);
console.log(" Direct object: " + directObject);
console.log(" Preposition: " + preposition);
console.log(" Indirect object: " + indirectObject);
} else {
console.log("String is not a match: " + strings[i]);
}
console.log(match);
}
私の正規表現は、最初と最後の3つの文字列に対して機能します。
他のメソッド(.split()など)を使用して正しい結果を取得する方法を知っています。これは正規表現を学習する試みなので、これを行う別の方法を探していません:-)
オプションの非キャプチャグループをさらに追加しようとしましたが、機能させることができませんでした。
var exp = /^([a-z]+)(?:\s([a-z0-9\s]+)(?:\s(on|with)\s([a-z\s]+))?)?$/i;
これは最初の3つの文字列では機能しますが、最後の3つの文字列では機能しません。
だから私が欲しいのは:最初の単語、指定された単語(「on」のような)までのいくつかの文字、文字列の終わりまでのいくつかの文字
トリッキーな部分は、さまざまなバリエーションです。
できますか?
実用的なソリューション:
exp = /^([a-z]+)(?:\s((?:(?!\s(?:on|with)).)*)(?:\s(on|with)\s(.*))?)?$/i;