我有一个关于如何为正则表达式实现可选部分的问题。我从解析好的文本冒险输入中得到了一个例子。这很好地突出了我的任务。这是一个展示我之后的例子的例子:
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);
}
我的正则表达式适用于第一个和最后三个字符串。
我知道如何使用其他方法(如.split())获得正确的结果。这是尝试学习正则表达式,所以我不想寻找另一种方法: - )
我尝试添加更多可选的非捕获组,但我无法让它工作:
var exp = /^([a-z]+)(?:\s([a-z0-9\s]+)(?:\s(on|with)\s([a-z\s]+))?)?$/i;
这适用于三个第一个字符串,但不适用于最后三个字符串。
所以我想要的是: 第一个单词,一些字符直到指定的单词(例如&#34; on&#34;),一些字符直到字符串结尾
棘手的部分是不同的变体。
可以吗?
工作解决方案:
exp = /^([a-z]+)(?:\s((?:(?!\s(?:on|with)).)*)(?:\s(on|with)\s(.*))?)?$/i;
答案 0 :(得分:2)
也许像这样的一些正则表达式:
var exp = /^([a-z]+)(?:(?:(?!\s(?:on|with))(\s[a-z0-9]+))+(?:\s(?:on|with)(\s[a-z0-9]+)+)?)?$/i;
小组\s[a-z0-9]+
会抓住一个以空格开头的单词。
(?!\s(?:on|with))
可以避免这个词“开启”或“有”。
因此(?:(?!\s(?:on|with))(\s[a-z0-9]+))+
是“on”或“with”之前的单词列表。
您可以测试here。