需要获得指定分隔符之间的匹配

时间:2019-07-05 10:04:24

标签: javascript regex

我正在尝试在句子中的双块引号定界符之间匹配特定的tags

Look for `foo="x"` ONLY between the specific double block quote delimiters  [[foo="x"|bar="y"|baz="z"]]

使用以下正则表达式还会在定界符之外匹配foo="x"

(?:(foo|bar|baz)="([^"]+)")+

我尝试在正后面添加(?<=\[\[),但是它只返回bockquotes中的第一个foo="x",而忽略了bar="y"baz="z"匹配项。

const regex = /(?:(foo|bar|baz)="([^"]+)")+/gm;
const str = `Look for \`foo="x"\` ONLY between the specific double block quote delimiters  [[foo="x"|bar="y"|baz="z"]]`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

2 个答案:

答案 0 :(得分:2)

如果您在[[]]中的字符串没有简单的[]

/(foo|bar|baz)="([^"]+)"(?=[^\][]*]])/g

将为您工作。 (?=[^\][]*]])部分将确保除[]之外还有0个或更多字符,然后]位于当前位置的右侧。参见regex demo

最安全的解决方案包括两个步骤:1)使用/\[\[((foo|bar|baz)="([^"]+)"(?:\|(foo|bar|baz)="([^"]+)")*)]]/获得Group 1值(或更简单但不那么精确但更通用的 /\[\[\w+="[^"]+"(?:\|\w+="[^"]+")*]]/g,请参见{{3 }})和2)使用/(foo|bar|baz)="([^"]+)"/g(或/(\w+)="([^"]+)"/g)从第1组提取必要的值。

const x = '(foo|bar|baz)="([^"]+)"';                         // A key-value pattern block
const regex = new RegExp(`\\[\\[(${x}(?:\\|${x})*)]]`, 'g'); // Extracting the whole `[[]]`
const str = `Look for \`foo="x"\` ONLY between the specific double block quote delimiters  [[foo="x"|bar="y"|baz="z"]]`;
let m;
while (m = regex.exec(str)) {
    let results = [...m[1].matchAll(/(foo|bar|baz)="([^"]+)"/g)]; // Grabbing individual matches 
    console.log(Array.from(results, m => [m[1],m[2]]));
}

\[\[((foo|bar|baz)="([^"]+)"(?:\|(foo|bar|baz)="([^"]+)")*)]]模式将匹配

  • \[\[-[[
  • ((foo|bar|baz)="([^"]+)"(?:\|(foo|bar|baz)="([^"]+)")*)-第1组:
    • (foo|bar|baz)-foobarbaz
    • =-=
    • "([^"]+)"-""以外的1个或更多字符和"
    • (?:\|(foo|bar|baz)="([^"]+)")*-|和上述模式的0次或多次重复
  • ]]-]]子字符串。

请参见demo

答案 1 :(得分:2)

稍微尝试一下您的需求定义:

  • 匹配 name =“ value” ,同时捕获 name value 的组,
  • 名称之前应为:
    • 两个双括号([[
    • 或竖线(|
  • (并用双引号引起来)之后应为:
    • 两个双括号(]]
    • 或竖线(|)。

然后正则表达式可以如下:

(?:\[\[|\|)(foo|ba[rz])="(\w+)"(?=]]|\|)

详细信息:

  • (?:\[\[|\|)-之前的内容(将是比赛的一部分, 而不是任何捕获组的一部分)
  • (foo|ba[rz])="(\w+)"-名称 / 对(带双引号),
  • (?=]]|\|)-之后的内容(这次表示为 正向前进)。

有关工作示例,请参见https://regex101.com/r/dj51GS/1