2017-05-06 1 views
1

私は以下のようなテキストブロックを持っています。他のパターン内に見つかった場合を除いて、文字列のすべての出現を見つける

data ...; 
... 
run; 

ここで...は任意のタイプの文字列パターンです。私はパターンがCスタイルのコメントの中にない場合や、以下のような別のパターンで囲まれている場合にのみ、これを発見したいと思います。私はすべての出現を見つけたい。

data foo; 
    set bar; 
run; 

なく

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

または

/* data foo;*/ 
/* set bar;*/ 
/* run;*/ 

それが唯一の最後の試合を返して、しかし私は、コメントや%macro ... %mendに包まれたときのパターンを除外します以下の機能を持っており、それぞれの出現ではない。ブロックごとに1つのリストを持つリストのリストとしてすべての一致を戻すにはどうすればよいですか?前もって感謝します。

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)) 

答えて

1

'%s.*?%s|%s.*?%s|(%s.*?%s)'へスキップsubregexes非貪欲、すなわち、変更'%s.*%s|%s.*%s|(%s.*?%s)'.* -partしてください。

デモ:

for match in datastep(s): 
    if match: 
     print(match) 

出力:

data foo_matchme; 
    set bar; 
run; 
data foo_matchme2; 
    set bar; 
run; 
+0

私は投稿後に同じ結論を見つけました。ありがとう! –

関連する問題