我正在尝试使用 Python 来处理数千行 SAS 代码。我想提取代码的某些部分进行打印或发送到另一个函数。
我正在查看的 SAS 代码可能如下所示:
"""%macro msg (name= some_macro) ;
%put Hello World, my name is &name ;
%mend ;"""
我想捕获第一行和最后一行之间的内容,即 %macro
和 %mend ;
行之间的内容,因此“%put Hello World ,我的名字是&name;”将作为一个组返回。
我可以通过以下方式实现此捕获:
re.compile(r"\%macro\s*?.*?\s*?\((.*)\)\s*?;\n(.*?)\n\s*\%mend\s*;")
由于 (.*?)\n
似乎与我想要的行匹配。
注意:我使用了很多 \s*
因为我看到 SAS 代码中到处都是空格,这似乎是相当随机的。
但是,当 SAS 代码超过更多行(可能是 2 行或更多行)时,我无法进行模式匹配,因此例如,
"""%macro msg (name= some_macro) ;
%put Hello World, my name is &name ;
%let something happen
%do something else
%mend ;"""
在这里,我想返回“%put Hello World,我的名字是&name;%让某事发生%做其他事情”作为一组返回。我尝试放入量词 *
和 +
但我不知道如何明确要检查整行重复,而不仅仅是最后一个字符我把量词放在旁边。我将以此为例:
r"\%macro\s*?.*?\s*?\((.*)\)\s*?;\n(.*?)\n+?\s*\%mend\s*;"
在这里,我试图指示 (.*?)\n
行可以重复 1 次到无限次,并且我想捕获该组。
我也尝试过使用 re.MULTILINE
和 re.DOTALL
,使用 ^ 和 $ 以及点作为行尾符,但没有达到预期的结果任何一个。
请帮助我更好地了解这个领域。谢谢
最佳答案
您可以使用单个捕获组并匹配不以 %mend 开头的行。
百分号不需要转义,请注意,如果不是有意的,\s
也可以匹配换行符。
%macro.*\r?\n((?:(?!\s*%mend).*\r?\n)+)\s*%mend ;
说明
%macro.*\r?\n
匹配 %macro,后跟该行的其余部分和换行符(
捕获组 1(?:
非捕获组(?!\s*%mend)
负向前看,如果右侧的内容不是%mend
.*\r?\n
匹配整行和换行符
)+
关闭非捕获组并重复 1 次以上以匹配至少一行
)
关闭捕获组 1\s*%mend ;
例如
pattern = re.compile(r"%macro.*\r?\n((?:(?!\s*%mend).*\r?\n)+)\s*%mend ;")
print(re.findall(pattern, test_str))
关于python - 使用 Regex 提取多行 SAS 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59530719/