【问题标题】:How to get all values in parentheses in a string including nested parentheses?如何获取字符串中括号中的所有值,包括嵌套括号?
【发布时间】:2019-07-03 05:24:02
【问题描述】:

期望的行为

我有一个输入验证,其中包括测试长度 (< 140 chars)。

我的输入接受降价,我想在我的长度计算中排除 URL 的长度。

例如,显示为:

这是Math.random()上这篇文章的一个很长的链接

57 个字符长,而它的实际代码是155 个字符长,即:

here is a very long link to this article on [Math.random()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random)

需要涵盖的场景如下:

text and [a markdown link](https://google.com)

text (and [a markdown link within parenthesis](https://google.com))

这个问题是关于:

如何获取字符串中括号中的所有值,包括嵌套括号。

我的尝试

我目前对整体问题的处理方法是:

  1. 获取字符串中括号内的所有值
  2. 如果有任何以https 开头的字符串,请创建该字符串的副本
  3. 从复制的字符串中删除值
  4. 获取调整后字符串的长度并对其进行运行长度验证

这些是我在第一部分的尝试:

01)

这个解决方案只得到第一个“匹配”,来源:https://stackoverflow.com/a/12059321

var text = "here is a (very) long link to this article on [Math.random()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random)";

var regExp = /\(([^)]+)\)/;

var matches = regExp.exec(text);
console.log(matches);
// 0: "(very)"
// 1: "very"

02)

此解决方案获取所有匹配项,包括括号,来源:https://stackoverflow.com/a/30674943

var text = "here is a (very) long link to this article on [Math.random()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random)";

var regExp = /(?:\()[^\(\)]*?(?:\))/g;

var matches = text.match(regExp);
console.log(matches);
// 0: "(very)"
// 1: "()"
// 2: "(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random)"

但是在嵌套括号的场景中它并没有按预期工作,即:

var text = "text (and [a markdown link within parenthesis](https://google.com))";

var regExp = /(?:\()[^\(\)]*?(?:\))/g;

var matches = text.match(regExp);
console.log(matches);
// ["(https://google.com)"]

03)

这里有一个php regex 解决方案似乎是相关的:

https://stackoverflow.com/a/12994041

但我不知道如何在 javascript 中实现该正则表达式,即:

preg_match_all('/^\\((.*)\\)[ \\t]+\\((.*)\\)$/', $s, $matches);

【问题讨论】:

  • 我建议找到一个呈现降价的库,然后根据输出进行验证。它可以让您的生活更轻松。
  • 嗯,我实际上已经使用markdown-it 来作为编辑器功能,我会查看文档。
  • 作为参考,似乎 markdown-it renderrenderInline methods 将 markdown 字符串渲染成 html,所以它仍然不会得到“纯文本”。我也使用DOMPurify 并查看了他们的文档,但它似乎不是为“将降价转换为文本”而设计的。

标签: javascript regex


【解决方案1】:

我会使用一个正则表达式,它还要求方括号中的部分位于括号内的链接之前。

/\[([^\]]+)\]\([^)]+\)/g

确保使用g 标志。这还包括一个捕获组,因此您可以将“可见”部分(方括号之间)与“不可见”的其余部分区分开来:

var text = "here is a (very) long link to this article on [Math.random()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random)";

var regExp = /\[([^\]]+)\]\([^)]+\)/g;

var match;
while (match = regExp.exec(text)) {
     console.log("full match: " + match[0]);
     console.log("keep: " + match[1]);
}

您实际上可以使用replace 调用来删除“不可见”部分。这使得计算可见字符的总数变得容易:

var text = "here is a (very) long link to this article on [Math.random()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random)";

var regExp = /\[([^\]]+)\]\([^)]+\)/g;

console.log("original length: " + text.length);
console.log("visible length: " + text.replace(regExp, "$1").length);

【讨论】:

  • 只是为了增加/确认对第一个解决方案的理解,您介意准确描述while 循环的工作原理吗?即我可以看到这意味着当something 为真时,记录值,当something 为假时停止。这是否意味着as long as the regex is returning matches, log values, otherwise stop。我正在阅读这篇文章,我认为这是对的,但只是想确认一下:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 确实,赋值发生在while 条件下(有些人可能会反对这种副作用,但通常是通过RegExp#exec 上的循环来完成的)。现在exec 总是返回一个对象(一个数组)或null。只有在后一种情况下,while 条件才会为假,并且在没有更多匹配项时发生。
【解决方案2】:

试试(?<=\()[^()]+(?=\))

解释:

(?<=\() - 积极地断言前面是(

[^()]+ - 匹配除() 之外的任何字符中的一个或多个

(?=\)) - 以肯定的前瞻方式断言接下来是)

Demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    • 2013-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    相关资源
    最近更新 更多