正则表达式匹配JavaScript中平衡分隔符之间的内容

时间:2018-04-08 14:18:28

标签: javascript regex

鉴于这些例子:

{{foo}}
{foo{bar}}
{bar}
baz

{quz
{foobar}}

预期的输出将是:

foo
foo{bar}
bar
baz

{quz
foobar}

也就是说,搜索任意文本女巫可能包含最多一个匹配,并替换平衡分隔符({})如果有任何使用正则表达式与字符串replace方法。

someStr.replace(/regexp goes here/, match => return match);

我知道括号对({}/\{(.*?)\}/,({{}}/\{\{(.*?)\}\}/的模式,但不知道如何组合0,1和括号中有2次出现在一个正则表达式中。

另外,为了只匹配没有分隔符的内容,我们应该使用外观断言https://stackoverflow.com/a/2973495/1553656

4 个答案:

答案 0 :(得分:2)

如果所有这些事件都在一个大文本中,即使具有更多特色正则表达式,也几乎不可能找到一个可行的答案,但如果它们是分开的输入字符串,则可能有一个解决方案。计算输入字符串开头的大括号数量,并在结尾处删除该数字中的右括号:

#include <initializer_list>
#include <numeric>

int memcpy_var() {
    return 0;
}

template<typename T, typename ... Ts>
int memcpy_var(T val, Ts ...rest) {
    return val + memcpy_var(rest...);
}

template<typename T, typename ... Ts>
int memcpy_var(std::initializer_list<T> il, Ts ...rest) {
    return std::accumulate(il.begin(), il.end(), 0) + memcpy_var(rest...);
}

int main() {
    return memcpy_var({1, 2, 3}, 5);
}

RegEx细分:

var inputStrings = [
    '{{foo}}',
    '{bar}',
    'baz',
    '{quz',
    '{foobar}}',
    '{foo{bar}}'
];

inputStrings.forEach(function(value) {
    var numberOfBracesAtStart = (value.match(/{/gy) || []).length;;
    console.log(value.replace(new RegExp("^\{{" + numberOfBracesAtStart + "}(.*)\}{" + numberOfBracesAtStart + "}$"), '$1'));
})
  • "^\{{" + X + "}(.*)\}{" + X + "}$" "^\{{" + X + "}"次开始时与{匹配
  • X匹配
  • 之间的任何内容
  • (.*)"\}{" + X + "}$"
  • 结束时匹配}

这样的正则表达式将用于X

{{foo}}

答案 1 :(得分:2)

递归使事情变得更容易和更短:

var trim = s => /^{.*}$/.test(s) ? trim(s.slice(1, -1)) : s;

var a = '{{foo}} {foo{bar}} {bar} baz  {quz {foobar}}'.split(' ');

console.log( a.map(trim).join('\n') );

答案 2 :(得分:1)

如果目标真的只是从每一行中删除相同数量的开始和结束分隔符,那么你也可以使用一个简单的循环来“计算”第一个和最后一个字符匹配的时间{和}分别,然后简单地返回适当长度的子串:

UPDATE t SET PrevAcceptID = 
  ISNULL(
      (SELECT TOP 1 AcceptID 
       FROM Test t2 
       WHERE t2.Station = t.Station AND t2.Period = t.Period AND t2.AcceptID < t.AcceptID ORDER BY StackDate DESC, QTime DESC), 
         AcceptID)
FROM Test AS t

甚至可以在这里使用var inputStrings = '{{foo}},{foo{bar}},{bar},baz,{quz,{foobar}}'.split(','); inputStrings.forEach(function(value) { var c = 0, l = value.length-1; while(value[c]==='{' && value[l-c]==='}') { c++; } console.log(value, "->", value.substring(c, l-c+1)); })循环,这样可以更加“直接”使用工具,这是最基本的目的:

for

答案 3 :(得分:0)

试试这个:

var arr = ["{{foo}}", "{foo{bar}}", "{bar}", "baz", "{quz", "{foobar}}"];
var regx = /^{{([^{}]+)}}|{{?(.*)}?}$/g;
var res = [];
for (var i = 0; i < arr.length; i++) {
  var match = arr[i].replace(regx, "$1$2");
  res.push(match);
}
console.log(res);