JavaScript正则表达式字符串匹配/替换

时间:2017-11-13 16:56:21

标签: javascript regex string

给出字符串; “{abc} Lorem ipsum {/ abc} {a} dolor {/ a}”

我希望能够找到大括号“标签”的出现,将标签和索引存储在找到的位置,并将其从原始字符串中删除。我想为每次出现重复这个过程,但是因为每次索引必须正确时我都会删除部分字符串...我找不到所有的索引然后在最后删除它们。对于上面的例子,应该发生的是;

  • 搜索字符串...
  • 在索引0
  • 处找到“{abc}”
  • 将{tag:“{abc}”,index:0}推入数组
  • 从字符串
  • 中删除“{abc}”
  • 重复步骤1,直到找不到更多匹配项

鉴于这个逻辑,“{/ abc}”应该在索引11处找到 - 因为“{abc}”已被删除。

我基本上需要知道这些“标签”的开始和结束位置,而不是将它们作为字符串的一部分。

我几乎在那里使用正则表达式,但它有时会跳过事件。

let BETWEEN_CURLYS = /{.*?}/g;
let text = '{abc}Lorem ipsum{/abc} {a}dolor{/a}';
let match = BETWEEN_CURLYS.exec(text);
let tags = [];

while (match !== null) {
    tags.push(match);
    text = text.replace(match[0], '');
    match = BETWEEN_CURLYS.exec(text);
}

console.log(text); // should be; Lorem ipsum dolor
console.log(tags);

/**
 * almost there...but misses '{a}'
 * [ '{abc}', index: 0, input: '{abc}Lorem ipsum{/abc} {a}dolor{/a}' ]
 * [ '{/abc}', index: 11, input: 'Lorem ipsum{/abc} {a}dolor{/a}' ]
 * [ '{/a}', index: 20, input: 'Lorem ipsum {a}dolor{/a}' ]
 */

1 个答案:

答案 0 :(得分:3)

您需要从正则表达式lastIndex值中减去匹配长度,否则下一次迭代的开始时间比预期的要长(因为输入变得更短,并且在您调用{lastIndex后不会更改replace {1}}删除{...}子字符串):

let BETWEEN_CURLYS = /{.*?}/g;
let text = '{abc}Lorem ipsum{/abc} {a}dolor{/a}';
let match = BETWEEN_CURLYS.exec(text);
let tags = [];

while (match !== null) {
    tags.push(match);
    text = text.replace(match[0], '');
    BETWEEN_CURLYS.lastIndex = BETWEEN_CURLYS.lastIndex - match[0].length; // HERE
    match = BETWEEN_CURLYS.exec(text);
}

console.log(text); // should be; Lorem ipsum dolor
console.log(tags);

还有一些RegExp#exec提到的内容:

  

如果正则表达式使用“g”标志,则可以多次使用exec()方法在同一字符串中查找连续匹配项。执行此操作时,搜索从正则表达式lastIndex属性指定的str子字符串开始(test()也将提升lastIndex属性)。