【问题标题】:Regular expression to match brackets正则表达式匹配括号
【发布时间】:2012-08-10 18:30:45
【问题描述】:

对于模板引擎,我使用正则表达式来识别字符串中括号内的内容。例如,正则表达式需要匹配 {key} 或 或 [element]。

目前我的正则表达式如下所示:

var rx=/([\[\{<])([\s\S]+?)([\]\}>])]/;

问题是这样的正则表达式不会强制括号匹配。例如在以下字符串中:

[{lastName},{firstName}]

正则表达式将匹配[{lastName}

有没有办法定义匹配的括号?例如,如果左括号是 [ 那么右括号必须是 ],而不是 } 或 >

【问题讨论】:

  • 请记住,方括号表达式中的字符通常会失去其特殊性。因此[[] 匹配左方括号,[{] 匹配左大括号,等等。
  • 听起来你需要的是解析器,而不是正则表达式。
  • 所有这些括号的意思是一样的吗?如果没有,你只需要不同的正则表达式
  • @ghoti 正确,我只是认为它的可读性更好。
  • 这是duplicate,但我只想说,不,你不能这样做。

标签: javascript regex


【解决方案1】:

最好的方法是拆分成 3 个正则表达式,特别是如果不同的括号可以有不同的含义:

var rx1 = /\[([^\]]+)]/;
var rx2 = /\(([^)]+)\)/;
var rx3 = /{([^}]+)}/;

这些将分别匹配由[](){} 包围的任何文本,其中的文本位于第一个匹配组中。

【讨论】:

  • (将这个标记为答案,因为它是第一个 - 在 cmets 中)
【解决方案2】:

您可以使用管道字符 (|) 的替代方法,例如 /\[([\s\S]+?)\]|\{([\s\S]+?)\}|&lt;([\s\S]+?)&gt;/,尽管它会很长。

编辑:缩短了正则表达式,不再那么长了...

【讨论】:

  • 您可以使用([^\]]+) 之类的东西来代替([\s\S]+?),这样可以更清楚地表明您正在匹配不包含结束括号(并且更短)的最长字符序列
【解决方案3】:
var rx = /\[[^\]]+\]|\{[^}]+\}|<[^>]+>/;

【讨论】:

  • 对,这与第一个答案类似。我实际上对使用您在另一篇文章中展示的对象感兴趣:{"[":"]","",...}。 for...in 循环中使用的对象可能有助于使模式更通用。
  • @Christophe。您接受的答案质量很差。您必须检查三个正则表达式的匹配项并进行比较:例如使用“{[abc]}”,第一个正则表达式将匹配 [abc] 这不是您想要的等等。此外,答案根本不处理 &lt;&gt; 并且它不必要地处理 ()。您没有义务仅仅因为它是半正确的就接受第一个答案 - 而您接受的答案甚至不是那个!
  • 嗯,这在当时听起来是个好主意......我实际上认为我在stackoverflow.com/questions/14334740/… 中发布的解决方案可能也很适合这里。
【解决方案4】:

有没有办法定义匹配的括号?例如说如果 左括号是 [ 然后右括号必须是 ],而不是 } 或 >

排序。

ERE 没有提供一种方法,让您可以按照您描述的方式将右括号与左括号匹配。 (也许可以使用 PREG 魔法,但我必须把它留给其他人。)你需要有多个正则表达式,或者一个正则表达式中有多个原子。

如果您使用单个正则表达式,我认为您需要确定要检测的括号字符串的 type 以及该字符串的内容。正如 cmets 中所提到的,您需要在您的编程语言中执行此操作,但您至少可以从正则表达式中获得所需的内容。

在下面的正则表达式中,每种样式的字符串在 RE 中都表示为一个“分支”。分支由 or-bars (|) 分隔。为清楚起见,我假设所有字符串都是[:alnum:]。您尚未指定内容,因此您需要根据您的特定要求进行调整。

/(\[)([[:alnum:]]+)\]|(\()([[:alnum:]]+)\)|(\{)([[:alnum:]]+)\}/
 ↑   ↑               ↑                    ↑
 $1  $2           divider              divider

请注意,在每个分支中,第一个字符都用圆括号括起来,使其成为“原子”。您需要您的代码像反向引用一样引用这个原子。第二个原子是内弦。现在......我的 JavaScript 不如我的烘焙技能那么强大,但这可能是一个开始:

String.prototype.bracketstyle = function() {
  var re = /(\[)([:alnum:]+)\]|(\()([:alnum:]+)\)|(\{)([:alnum:]+)\}/;
  return this.replace(re,"$1");
}

String.prototype.innerstring = function() {
  var re = /(\[)([:alnum:]+)\]|(\()([:alnum:]+)\)|(\{)([:alnum:]+)\}/;
  return this.replace(re,"$2");
} 

我怀疑您可以将它们组合成一个函数,或者以不同的方式使用它们而不使它们成为函数,但您明白了。

【讨论】:

  • 这看起来与第一个答案相似。但恐怕 JavaScript 看不懂 :alnum:
  • [:alnum:] 只是[A-Za-z0-9] 的捷径。
  • 不是什么捷径 ;-) 没错,它适用于多种语言,但不适用于 JavaScript。
  • 我的意思是,如果[[:alnum:]]+ 不适合您,只需将其替换为[A-Za-z0-9]+
猜你喜欢
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-18
  • 2016-02-13
  • 2013-06-18
相关资源
最近更新 更多