Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/404.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript正则表达式中的可选部分(带有捕获组)_Javascript_Regex_Expression - Fatal编程技术网

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;