You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

正则匹配带任意嵌套大括号的Main函数块内容问题

解决正则匹配最外层嵌套大括号的问题

这个问题太常见了——普通正则的非贪婪匹配搞不定嵌套的大括号结构,因为它没法追踪括号的层级,所以会在第一个遇到的}就停下来。下面给你两种靠谱的解决方案,根据你用的正则引擎选就行:

1. 使用递归正则(支持PCRE、JS ES2018+、Python regex库等)

如果你的正则引擎支持递归匹配(比如PHP的PCRE、JavaScript ES2018及以后版本、Python第三方regex库),可以用平衡组逻辑来精准匹配嵌套的大括号。

正则表达式示例

^Main:\s*\w*\(\s*\)\s*\{\s*((?:[^{}]|(?R))*?)\s*\}$

各部分解释

  • ^Main:\s*\w*\(\s*\)\s*\{:精准匹配Main: Subroutine( ) {这类开头,兼容任意空白字符
  • ((?:[^{}]|(?R))*?):核心捕获组,匹配两种内容:
    • [^{}]:任何不是大括号的字符
    • (?R):递归匹配整个正则模式(也就是处理嵌套的{...}结构)
    • *?:非贪婪模式,确保只匹配到最外层的}
  • \s*\}$:匹配结尾的右大括号,忽略前后空白

Python(使用regex库)代码示例

import regex

your_text = """...上方还有其他带{ block }的代码块...
Main: Subroutine( ) {
Include(foo = bar )
Call(foo = bar )
Repeat(foo = ibar ) {
Message("Message = bar number {ibar}" foo )
Something( )
Message("Message = foo {bar}" )
}
Message("Message = again {iterations}" )
For(start = foo , end = bar ) {
Comment( )
}
While(foo ) {
Comment( )
}
Comment( )
}
...下方还有其他带{ block }的代码块..."""

pattern = r'^Main:\s*\w*\(\s*\)\s*\{\s*((?:[^{}]|(?R))*?)\s*\}$'
match_result = regex.search(pattern, your_text, flags=regex.MULTILINE)

if match_result:
    print("匹配到的内容:")
    print(match_result.group(1))

2. 计数法(兼容所有正则引擎,适合不支持递归的场景)

如果你的正则引擎不支持递归(比如Python标准库的re模块),可以用手动计数大括号层级的方法来找到最外层的结束括号:

Python(标准re库)代码示例

import re

your_text = """...上方还有其他带{ block }的代码块...
Main: Subroutine( ) {
Include(foo = bar )
Call(foo = bar )
Repeat(foo = ibar ) {
Message("Message = bar number {ibar}" foo )
Something( )
Message("Message = foo {bar}" )
}
Message("Message = again {iterations}" )
For(start = foo , end = bar ) {
Comment( )
}
While(foo ) {
Comment( )
}
Comment( )
}
...下方还有其他带{ block }的代码块..."""

# 先定位Main子例程的起始左大括号
start_match = re.search(r'^Main:\s*\w*\(\s*\)\s*\{', your_text, flags=re.MULTILINE)
if not start_match:
    print("未找到匹配的Main子例程")
else:
    start_pos = start_match.end()
    brace_level = 1  # 已经匹配了一个左大括号
    content_chars = []
    
    # 逐字符遍历,追踪括号层级
    for idx in range(start_pos, len(your_text)):
        char = your_text[idx]
        if char == '{':
            brace_level += 1
        elif char == '}':
            brace_level -= 1
            if brace_level == 0:
                # 找到最外层的右大括号,停止遍历
                break
        content_chars.append(char)
    
    # 整理结果,去掉首尾空白
    matched_content = ''.join(content_chars).strip()
    print("匹配到的内容:")
    print(matched_content)

为什么你原来的正则不行?

你写的/^Main:\s*\w*\(\s*\)\s*\{\s*((?:.*\s*)*?)\}$/gm里的(?:.*\s*)*?无差别匹配任意字符,它没法区分嵌套的}和最外层的},所以遇到第一个}就会终止匹配,自然拿不到完整的最外层内容。

内容的提问来源于stack exchange,提问作者shiiboun

火山引擎 最新活动