如果你可以假设一个函数的 END 总是在行的开头没有缩进,而所有其他的都是缩进的,如果设置为多行模式m
(大多数正则表达式引擎的标志),这个正则表达式将起作用。您还需要“点匹配所有内容”标志 ( s
)。
FUNCTION\s+[a-z0-9_]+\s+IS\s+(.+?)^END
这里的技巧是^END
,它告诉它只匹配行首的 END 。锚点仅在多行模式下具有^
此含义,因此如果您的正则表达式引擎需要它,请确保添加 m 标志(Ruby 的不需要,大多数其他人需要)。
要分别捕获定义和代码:
FUNCTION\s+[a-z0-9_]+\s+IS\s+(.+?)\s+BEGIN\s+(.+?)^END
如果您总是在“END”语句中提供函数的名称,就像您在编辑中所做的那样,那么无论缩进如何,这个正则表达式都将起作用。您需要“点匹配所有内容”标志 ( s
)。
FUNCTION\s+([a-z0-9_]+)\s+IS\s+(.+)\s+END\s+\1\s*;
这里我使用的是反向引用:END\s+\1\s*;
将匹配 END,后跟至少一个空格,然后是函数名称(之前捕获的),然后是任意数量的空格和一个分号。
要分别捕获定义和代码:
FUNCTION\s+([a-z0-9_]+)\s+IS\s+(.+?)\s+BEGIN\s+(.+)\s+END\s+\1\s*;
如果您不能对缩进做出假设,并且如果所有函数在“END”语句中都没有它们的名称,那么我想不出一个可以完成这项工作的正则表达式。
当涉及到递归模式时,正则表达式通常不是正确的工具(好吧,一些高级正则表达式引擎中有一种方法可以递归整个模式,但它并不适用于所有情况,而且很难使用)。
所以我会用手做。循环遍历字符,检测函数的开头(您可以使用一个简单的正则表达式),然后为每个“BEGIN”递增一个计数器,并为每个“END”递减它(注意不要用“END IF”递减) )。当计数器降至零时,您的功能就结束了。