【问题标题】:Regex to parse out values in parentheses正则表达式解析括号中的值
【发布时间】:2017-11-02 03:09:35
【问题描述】:

我希望能够通过空格分隔将字符串分隔为值,但如果括号中的内容我需要它在单个值中。例如,(a b c) d e (f g) h 应该变成 ['a b c', 'd', 'e', 'f g', 'h']。什么是正则表达式可以为我做到这一点?

【问题讨论】:

  • '(a b c) d e (f g) h'.match(/\([^\)]+\)|\S+/g) 似乎接近该输入。也许加入一些捕获组并循环使用.exec()?输入中的任何括号是否保证是平衡的?它们可以嵌套吗?
  • @nnnnnn 不,我不能保证它们是平衡的,但它们应该是平衡的,所以如果它们不平衡,无论如何它应该会引发错误。
  • @nnnnnn 也不行,它们不能嵌套。
  • 基于@nnnnnn 的回答尝试:string.match(/\([^\)]+\)|\S+/g).map(x => x.replace(/[\(\)]/g,""))
  • 使用正则表达式处理嵌套可能很困难或不可能。使用循环逐个字符读取字符串会更容易,并计算嵌套的深度。

标签: javascript regex parsing


【解决方案1】:

正如 cmets 中提到的,在正则表达式中处理嵌套是不可能的,所以这是处理您问题的代码;它使用正则表达式和其他技术:

var str = '(a (b) c) d e (f g) h';
var match;
var myRe = /\([^]+?\)|\S+/g;
var result = [];

while (match = myRe.exec(str)) {
  result.push(match[0]);
}

var tmp = "";
var final = [];
for (var i = 0; i < result.length; i++) {
  var leftP = (result[i].match(/\(/g) || []).length;
  var rightP = (result[i].match(/\)/g) || []).length;
  if (leftP !== rightP) {
    tmp += result[i];
    for (var j = i + 1; j < result.length; j++) {
      tmp += result[j];
      if ((tmp.match(/\(/g) || []).length === (tmp.match(/\)/g) || []).length) {
        final.push(tmp);
        tmp = "";
        i = j + 1;
        break;
      }
    }
  } else {
    final.push(result[i]);
  }
}
for (var i = 0; i < final.length; i++) {
  final[i] = final[i].replace(/\)(\S+)/g, ') $1');
}
for (var i = 0; i < final.length; i++) {
  final[i] = final[i].replace(/^\(([^]+)\)$/, '$1');
}

它可能没有优化,但我认为它可以解决您的问题。

【讨论】:

    【解决方案2】:

    没错,标准的 JavaScript 正则表达式引擎无法处理嵌套模式。如果您使用 Perl、PHP 或 .NET,您可以使用 this 之类的模式:

    (?(DEFINE)
      (?<open>\()
      (?<close>\))
      (?<val>(?&open)|(\w\s?)+)
      (?<start>(?&open)(?&val)(?&close))
    )
    (?&start)|(?<=\s)\w
    

    也可以使用扩展的 JavaScript 正则表达式库,如 XRegExp,在 JavaScript 中完成。这是一个示例,可以为您提供思路:

    const str1 = '(a b c) d e (f g) h';
    var s = XRegExp.matchRecursive(str1, '\\(', '\\)', 'g');
    console.log(s);
    // -> ['a b c', 'f g']
    

    【讨论】:

      猜你喜欢
      • 2011-09-05
      • 1970-01-01
      • 2014-11-27
      • 2015-12-30
      • 2011-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多