Javascript 使用RegExp分割数组中的值,模式只工作一半的时间

Javascript 使用RegExp分割数组中的值,模式只工作一半的时间,javascript,regex,Javascript,Regex,我试图使用RexExp和JS解析圣经经文。输出并不重要,因为我的一些正则表达式给了我错误的否定(除非我只是不了解关于正则表达式的某些内容,可能就是这样) 考虑以下功能: function wtf() { var s = "1:1-8, 3:5, 4:-8-10, 25-36, 5:1-6:1-26, 32-40, 55, 7:8", exp1 = new RegExp('(\\d+:)?([\\d-]+(?=\\d:)|[\\d-]+)','g'), result = s.split(ex

我试图使用RexExp和JS解析圣经经文。输出并不重要,因为我的一些正则表达式给了我错误的否定(除非我只是不了解关于正则表达式的某些内容,可能就是这样)

考虑以下功能:

function wtf() {
 var s = "1:1-8, 3:5, 4:-8-10, 25-36, 5:1-6:1-26, 32-40, 55, 7:8",
 exp1 = new RegExp('(\\d+:)?([\\d-]+(?=\\d:)|[\\d-]+)','g'),
 result = s.split(exp1),
 exp2 = new RegExp('\\d+[ :]+','g'), //tests for \d:
 exp3 = new RegExp('\\d+[-]\\B','g'), //tests for \d-
 exp4 = new RegExp('\\b\\d{1,3}[ -]+\\d{1,3}\\b','g'), //tests for \d-\d
 exp5 = new RegExp('\\d:.*\\b','g'), //tests for d: followed by anything
 exp6 = new RegExp('^\\d{1,3}$','g'), //tests for 1,12,123,etc.
 output = [];

 for(i=0;i<result.length;i++) {
        var t = String(result[i]);
        if(result[i] == "" | result[i] == ","| result[i] == " ," | result[i] == ", " | result[i] == undefined) {} 
        else if(exp5.test(result[i]) == true) {}
        else {output[i] = result[i];}
    }

    output = output.filter(function(val){return val});

 console.log(JSON.stringify(output));

 for(i=0;i<output.length;i++) {
    if(exp2.test(output[i]) == true) { //tests for '3:','10:','100:', etc
        console.log("Current Index: "+output[i]);
        console.log("IF Branch: "+exp2);
     }
     else if(exp4.test(output[i]) == true){//tests for '1-1','12-34','123-456', etc.
        console.log("Current Index: "+output[i]);
        console.log("IF Branch: "+exp4);
     }
     else if(exp3.test(output[i]) == true) { //tests for '/\\d[-]\\B/g'
        console.log("Current Index: "+output[i]);
        console.log("IF Branch: "+exp3);
     }
     else if(exp6.test(output[i]) == true) { //tests for '1','12','123',etc.
        console.log("Current Index: "+output[i]);
        console.log("IF Branch: "+exp6);
     }
     else {
        console.log("Current Index: "+output[i]);
        console.log("IF Branch: else");
     }
  console.log("");
 }
}
正如您所知,首先是JSON.stringified数组,然后是数组索引的循环。对于每个索引,输出索引匹配的值和模式。您会注意到,当索引值为“25-36”、“32-40”和“8”时,会触发else分支,即使它们都与使用的模式明显匹配。此外,在每种情况下,前面的索引的格式与触发if语句的相应分支的格式完全相同


到底发生了什么事?我对这里发生的事有什么不明白的?我正在检查以确保regex101上的模式是正确的,因此我确信它们正在工作。给出了什么?

您正在创建带有全局标志的正则表达式,它在匹配中保持其状态:

var re = /\d/g;
re.exec('123')  // ['1']
re.exec('123')  // ['2']
re.exec('123')  // ['3']
re.exec('123')  // null
因此,对于
测试

var re = /\d/g;
re.test('123')  // true
re.test('123')  // true
re.test('123')  // true
re.test('123')  // false
解决方案:不要在不需要全局标志时添加它

一般简化:

const output = [
    "1:1-8", "3:5", "4:-8-10", "25-36", "5:1-6:1-26", "32-40", "55", "7:8"];

const patterns = [
    /\d+[ :]+/,
    /\b\d{1,3}[ -]+\d{1,3}\b/,
    /\d+[-]\B/,
    /^\d{1,3}$/,
];

output.forEach(t => {
    const matched = patterns.find(p => p.test(t));

    console.log("Item: " + t);
    console.log("Matched: " + matched);
    console.log();
});

您正在创建带有全局标志的正则表达式,该标志在匹配中保持其状态:

var re = /\d/g;
re.exec('123')  // ['1']
re.exec('123')  // ['2']
re.exec('123')  // ['3']
re.exec('123')  // null
因此,对于
测试

var re = /\d/g;
re.test('123')  // true
re.test('123')  // true
re.test('123')  // true
re.test('123')  // false
解决方案:不要在不需要全局标志时添加它

一般简化:

const output = [
    "1:1-8", "3:5", "4:-8-10", "25-36", "5:1-6:1-26", "32-40", "55", "7:8"];

const patterns = [
    /\d+[ :]+/,
    /\b\d{1,3}[ -]+\d{1,3}\b/,
    /\d+[-]\B/,
    /^\d{1,3}$/,
];

output.forEach(t => {
    const matched = patterns.find(p => p.test(t));

    console.log("Item: " + t);
    console.log("Matched: " + matched);
    console.log();
});

不要使用
RegExp
构造函数,不要编写
==true
,不要命名变量编号。相反,
if(/\d+[:]+/.test(输出[i])){
@Ryan很好的建议。但是我尝试了它们,从小异常到每个测试都返回false。然后我返回并输出循环每次迭代中每个索引的所有四个测试的返回值,所有的值都是false。我一定会研究RegExp构造函数,看看它有什么问题它…不要使用
RegExp
构造函数,不要编写
==true
,不要命名变量编号。相反,
if(/\d+[:]+/.test(输出[i])){
@Ryan很好的建议。但是我尝试了它们,从小异常到每个测试都返回false。然后我返回并输出循环每次迭代中每个索引的所有四个测试的返回值,所有的值都是false。我一定会研究RegExp构造函数,看看它有什么问题这…这是正确的解决方案。谢谢你的解释!这是正确的解决方案。谢谢你的解释!