我需要一个正则表达式来选择两个外括号之间的所有文本。
例子: START_TEXT(这里的文本(可能的文本)文本(可能的文本(更多的文本))END_TXT ^ ^
结果: (此处文本(可能的文本)文本(可能的文本(更多的文本)))
我需要一个正则表达式来选择两个外括号之间的所有文本。
例子: START_TEXT(这里的文本(可能的文本)文本(可能的文本(更多的文本))END_TXT ^ ^
结果: (此处文本(可能的文本)文本(可能的文本(更多的文本)))
当前回答
我想添加这个答案,以便快速参考。请随时更新。
.NET Regex使用平衡组:
\((?>\((?<c>)|[^()]+|\)(?<-c>))*(?(c)(?!))\)
其中c用作深度计数器。
在Regexstorm.com上进行演示
堆栈溢出:使用正则表达式来平衡匹配括号 Wes令人困惑的博客:平衡结构与。net正则表达式的匹配 Greg Reinacker的Weblog:正则表达式中的嵌套结构
使用递归模式的PCRE:
\((?:[^)(]+|(?R))*+\)
演示在regex101;或无交替的:
\((?:[^)(]*(?R)?)*+\)
演示在regex101;或为表演而展开:
\([^)(]*+(?:(?R)[^)(]*)*+\)
演示在regex101;模式被粘贴在(?R)处,它表示(?0)。
Perl, PHP, notepad++, R: Perl =TRUE, Python: PyPI正则表达式模块与(?V1)的Perl行为。 (新版本的PyPI regex包已经默认为this→DEFAULT_VERSION = VERSION1)
Ruby使用子表达式调用:
与Ruby 2.0 \g<0>可以用来调用完整的模式。
\((?>[^)(]+|\g<0>)*\)
在Rubular演示;Ruby 1.9只支持捕获组递归:
(\((?>[^)(]+|\g<1>)*\))
Rubular的演示(从Ruby 1.9.3开始进行原子分组)
API JavaScript
XRegExp.matchRecursive(str, '\\(', '\\)', 'g');
Java: @jaytea使用前向引用的有趣想法。
不递归最多3层嵌套: (JS, Java和其他类型的正则表达式)
为了防止不平衡时失控,只在最内层[)(]上使用*。
\((?:[^)(]|\((?:[^)(]|\((?:[^)(]|\([^)(]*\))*\))*\))*\)
演示在regex101;或展开以获得更好的性能(首选)。
\([^)(]*(?:\([^)(]*(?:\([^)(]*(?:\([^)(]*\)[^)(]*)*\)[^)(]*)*\)[^)(]*)*\)
演示在regex101;需要根据需要添加更深层次的嵌套。
参考-这个正则表达式是什么意思?
递归正则表达式 Regular- expressions .info -正则表达式递归 精通正则表达式- Jeffrey E.F. Friedl 1 2 3 4
其他回答
答案取决于您是需要匹配括号的匹配集,还是只需要匹配输入文本中的第一个开始到最后一个结束的括号。
如果您需要匹配匹配的嵌套括号,那么您需要的不仅仅是正则表达式。-见@dehmann
如果只是先开后关,再见@扎克
决定你想要发生什么:
abc ( 123 ( foobar ) def ) xyz ) ghij
您需要决定在这种情况下您的代码需要匹配什么。
正则表达式是一个错误的工具,因为你正在处理嵌套结构,即递归。
但是有一个简单的算法可以做到这一点,我在之前的问题的回答中详细描述了它。其要点是编写代码扫描字符串,并对尚未与闭括号匹配的开括号保持计数器。当计数器返回0时,您就知道已经到达了最后的右括号。
这可能有助于匹配平衡括号。
\s*\w+[(][^+]*[)]\s*
我没有使用正则表达式,因为它很难处理嵌套代码。因此,这个代码片段应该能够允许你抓取带有平衡括号的代码段:
def extract_code(data):
""" returns an array of code snippets from a string (data)"""
start_pos = None
end_pos = None
count_open = 0
count_close = 0
code_snippets = []
for i,v in enumerate(data):
if v =='{':
count_open+=1
if not start_pos:
start_pos= i
if v=='}':
count_close +=1
if count_open == count_close and not end_pos:
end_pos = i+1
if start_pos and end_pos:
code_snippets.append((start_pos,end_pos))
start_pos = None
end_pos = None
return code_snippets
我使用它从文本文件中提取代码片段。
我写了一个叫做balanced的JavaScript库来帮助完成这个任务。你可以这样做
balanced.matches({
source: source,
open: '(',
close: ')'
});
你甚至可以做替换:
balanced.replacements({
source: source,
open: '(',
close: ')',
replace: function (source, head, tail) {
return head + source + tail;
}
});
下面是一个更复杂的交互式示例JSFiddle。