Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/469.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 - Fatal编程技术网

Javascript 确定在使用'|';正则表达式中的运算符

Javascript 确定在使用'|';正则表达式中的运算符,javascript,regex,Javascript,Regex,我有一个正则表达式,它是由一个“|”、aka或操作符拼凑而成的,它由更小的子模式组成。我试图确定匹配了哪个子模式,但是RegExp引擎只会给我整个表达式 示例: 以下是我的编译(近似)分段表达式(为了理解,进行了大量简化: /^somestring-(\w+)$|^notherstring-(\d+)-(\w+)$|^laststring-(\w+)-([a-f])$/g 以下是输入文本: laststring-eof 因此,在我的matches数组中,我看到了一些带有“未定义值”的索引(因

我有一个正则表达式,它是由一个“|”、aka或操作符拼凑而成的,它由更小的子模式组成。我试图确定匹配了哪个子模式,但是RegExp引擎只会给我整个表达式

示例:

以下是我的编译(近似)分段表达式(为了理解,进行了大量简化:

/^somestring-(\w+)$|^notherstring-(\d+)-(\w+)$|^laststring-(\w+)-([a-f])$/g
以下是输入文本:

laststring-eof
因此,在我的matches数组中,我看到了一些带有“未定义值”的索引(因为之前有几个尝试的匹配与整个表达式不匹配),但我也得到了匹配“eof”

这一切都很好,给了我大部分我想要的。我没有得到我需要的,是知道匹配的子模式是“^laststring-(\w+)$”,或者至少,知道这是主表达式中的第三个子模式。我不能依赖匹配数组的长度,因为每个子模式可以有无限多个匹配组


我尝试了regexp.lastIndex,但该属性只提供子模式中的最后一个匹配项,而不是整个表达式中子模式的偏移量。

我不确定这是否可行,但我认为如果您将()在每个子组周围的括号中,如果表达式匹配,您应该能够检查其中哪些是非空的,这样您就可以看到哪些模式匹配

在您的情况下,这将创建3个额外的子组,如果我计算正确,它将如下所示:

第一组=第一个子模式

第二组=第一子模式中的第一个匹配组

第三组=第二个子模式

第四组和第五组=第二个子模式中的子模式

第六组=第三分组


因此,您可以检查第一个、第三个和第六个匹配组,其中一个组为非空,这是您的匹配模式。

了解哪个分支匹配的唯一方法是查看结果数组中存在哪些组:

s = "laststring-eof";
p = /^somestring-(\w+)$|^notherstring-(\d+)-(\w+)$|^laststring-(\w+)-([a-f])$/g;
m = p.exec(s);
if (m[1] !== undefined) { /* first branch */ }
else if (m[2] !== undefined) { /* second branch */ }
else if (m[4] !== undefined) { /* last branch */ }
当不同的分支从其他模式拼凑在一起时,您需要计算每个模式中捕获组的数量:

function countCapturingGroups(regexp) {
    var count = 0;
    regexp.source.replace(/\[(?:\\.|[^\\\]])*\]|\\.|(\()(?!\?)/g,
        function (full, capturing) {
            if (capturing) count++;
        });
    return count;
}
对于没有捕获组的分支,可以添加空捕获:

p = /^somestring-(\w+)$|()^nocaptures$/g;
如果不能保证包括第一组,也可以对其他分支执行此操作

一个较长的例子:

function MultiRegExp(patterns)
{
    this.patterns = patterns;
    this.combined = new RegExp(patterns.map(function (p) {
        return "()" + p.source;
    }).join("|"));
    this.numcaptures = patterns.map(countCapturingGroups);
    this.start = [1];
    for (var i = 1; i < numcaptures.length; i++) {
        this.start[i] = this.start[i-1] + this.numcaptures[i-1] + 1;
    }
}

MultiRegExp.prototype.exec = function (str) {
    var m = this.combined.exec(str);
    if (!m) return;
    for (var i = 0; i < this.numcaptures.length; i++) {
        var offset = this.start[i];
        if (m[offset] !== undefined) {
            var result = [i,m[0]];
            for (var j = 1; j <= this.numcaptures[i]; j++) {
                result.push(m[offset + j]);
            }
            return result;
        }
    }
};

var p = new MultiRegExp([
    /^somestring-(\w+)$/,
    /^notherstring-(\d+)-(\w+)$/,
    /^laststring-(\w+)-([a-f])$/,
    /^nocaptures$/
]);

p.exec("somestring-abc"); // -> [0, "somestring-abc", "abc"]
p.exec("nocaptures"); // -> [3, "nocaptures"]
函数MultiRegExp(模式) { 这个模式=模式; this.combined=newregexp(patterns.map)(函数(p){ 返回“()”+p.source; }).加入(“|”); this.numcaptures=patterns.map(countCapturingGroups); this.start=[1]; 对于(变量i=1;i[3,“无职务”]
我怀疑您需要为3个不同的regexs@rpaskett首先修复不平衡的括号对
()
你不能简单地查看捕获的匹配来确定这一点(即它是否以
somestring
notherstring
,等等开始)?OP说这个例子“大大简化了”我目前正在进行3种不同的正则表达式匹配(在本例中),但正如我所提到的,子模式的数量是不确定的,最终可能是100+。我想在较小的正则表达式上进行100次匹配比匹配一个更大的表达式要慢。我可能是错的,但我仍然想知道如何完成我提出的任务。我实际上走了这条路,而且是确定的这是一种可能性,但我不能完全正确地理解。当每个子模式返回的匹配数不同时,会变得很混乱。如果你有一个例子,请分享。我的想法更多的是,你总是知道哪个匹配组对应于你搜索的子模式,但我不确定我是否正确理解了你的问题这有一个问题。我想如果你构造正则表达式,你总是可以计算你放入的匹配组的数量,看看哪些组对应于整个模式。然后你可以测试每个组是否匹配。我不确定为什么子模式返回的匹配数是个问题。所以我的意思是ke,有了matcher,调用matcher.matches(),然后检查是否(matcher.group(第一子模式的索引)!=null)如果子模式匹配。我不确定为什么返回的子模式数量会使这变得困难。或者知道子模式组的索引有问题吗?我认为问题在于组是基于左括号位置以平铺方式编号的,因此您无法知道没有k的第二个顶级组的编号现在知道第一个顶级组有多少个子组。大概,OP是将一些非文字的备选方案连接在一起,不想扫描每个备选方案,包括括号。但我真的认为从技术上讲,没有真正的备选方案。我想这将有助于了解更多关于他如何生成整个模式的信息。应该总是有一些方法来计算有多少子组,在最坏的情况下,我认为他可以将整个模式构造为一个字符串,然后在构造模式后搜索中间有多少子组。这是行不通的,因为它假设每个子模式都有精确的匹配数,如示例所示。模式会根据某些情况而变化。这也可能是:/^new-somestring-(\w+)-(\D{2})-(\D)$|^oldstring-(\D+)-(\w+)$| ^examplestring-(\w+)$/g@rpaskettexamp