Python 查找字符串的所有匹配项,除非在另一个模式中找到

Python 查找字符串的所有匹配项,除非在另一个模式中找到,python,regex,Python,Regex,我有下面这样的文本块,我希望找到所有出现的 data ...; ... run; data foo; set bar; run; 在哪里。。。可以是任何类型的字符串模式。我只想在模式不在C风格注释中或者它被包装在另一个模式中(如下面所示)的情况下找到这种情况。我想找到所有的事件 data ...; ... run; data foo; set bar; run; 但不是 %macro x(); data foo; set bar; run;

我有下面这样的文本块,我希望找到所有出现的

data ...;
...
run;
data foo;
    set bar;
run;
在哪里。。。可以是任何类型的字符串模式。我只想在模式不在C风格注释中或者它被包装在另一个模式中(如下面所示)的情况下找到这种情况。我想找到所有的事件

data ...;
...
run;
data foo;
    set bar;
run;
但不是

%macro x();
    data foo;
        set bar;
    run;
%mend;

我有以下函数,当包装在注释或
%macro…%中时,它将排除模式mend
但是它只返回最后一次匹配,而不是每次出现。我如何调整它,以将每个匹配作为列表列表返回,每个块有一个列表?提前谢谢

s = """
/**
* @file
* @brief    Description of the program
*/

/**
* @macro    xyz
* @brief    Description of the Macro
*/
%macro xyz();
    data foo_nomatch;
        set bar;
    run;
%mend;

/**
* @data     foo_matchme
* @brief    Description of the DataStep
*/
data foo_matchme;
    set bar;
run;

# Should Not Match
/** 
* data foo_nomatch2;
*      set bar;
* run;
*/

/**
* @datastep:    foo2
* @brief:       This is a description.
*/
# Should match as a 2nd match
data foo_matchme2;
    set bar;
run;
"""
def datastep(s):
    t1 = 'data'
    t2 = 'run;'
    t3 = ';'
    e1 = re.escape('/**')
    e2 = re.escape('*/')
    e3 = re.escape('%macro')
    e4 = re.escape('%mend')

    return re.findall('%s.*%s|%s.*%s|(%s.*?%s)' %(e1,e2,e3,e4,t1,t2),s,re.DOTALL|re.IGNORECASE)

print(datastep(s))

使跳过子区域的
*
-部分不贪婪,即将
'%s.*%s.*%s.*%s.*%s.
更改为
'%s.*%s.*%s.*%s.*%s.*%s.

演示:

输出:

data foo_matchme;
    set bar;
run;
data foo_matchme2;
    set bar;
run;

我只是在发帖后发现了同样的结论。谢谢