javascript正则表达式中的可选部分(带有捕获组)
我有一个关于如何实现正则表达式的可选部分的问题。我以解析好的旧文本冒险输入为例。这很好地突出了我的任务。下面是一个例子来说明我的目标:javascript正则表达式中的可选部分(带有捕获组),javascript,regex,expression,Javascript,Regex,Expression,我有一个关于如何实现正则表达式的可选部分的问题。我以解析好的旧文本冒险输入为例。这很好地突出了我的任务。下面是一个例子来说明我的目标: 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 t
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);
}
这适用于前三个字符串,但不适用于后三个字符串
所以我想要的是:
第一个单词,一些字符直到指定的单词(如“on”),一些字符直到字符串结束
棘手的部分是不同的变体
能做到吗
工作解决方案:
exp = /^([a-z]+)(?:\s((?:(?!\s(?:on|with)).)*)(?:\s(on|with)\s(.*))?)?$/i;
也许有些正则表达式是这样的:
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))
避免使用“on”或“with”这个词
因此,(?:(?!\s(?:on | with))(\s[a-z0-9]+)+
是“on”或“with”之前的单词列表
您可以进行测试。
?:
只生成一个不匹配的组,与可选组无关。可选组的末尾有一个?
,或者被量化为明显可选,如{0,1}
。但是,使用这么多可选组是没有意义的,因为您需要检查每个匹配组是否存在。我知道?:表示非捕获组。我尝试使用以下语法将其设置为可选:(?:此部分是可选的)
我认为问题在于第一个可选组定义太贪婪。它匹配字符串的其余部分,不仅仅是在“on”或“with”这个词没有完全满足我的要求之前,而是朝着正确的方向迈出了一步。“生锈的小钥匙”变成了“钥匙”,“木桌”变成了“桌子”。但正如我所说,这是朝着正确方向迈出的一步。我想那是什么-第二部分是让它发挥作用的关键。你想要什么?也许通过移动第一组单词中的第一个?:
:((?:(?!\s(?:on | with))(?:\s[a-z0-9]+)+(?:\s(?:on | with)(\s[a-z0-9]+)?$。我不确定Stackoverflow的做法是什么,但这个答案将我引向了正确的方向。我的解决方案是exp=/^([a-z]+)(?:\s((?:(?!\s(?:on | with)))*(?:\s(on | with)\s(.*))?$/i代码>好的,事实上,您主要是将字母数字单词[a-z0-9]+
替换为任何一组字符(*)
。如果那样的话,那就太好了!
var exp = /^([a-z]+)(?:(?:(?!\s(?:on|with))(\s[a-z0-9]+))+(?:\s(?:on|with)(\s[a-z0-9]+)+)?)?$/i;