2016-04-19 32 views
3

我正在閱讀一個文本文件,並試圖捕獲每個不同標籤的參數之一,該參數尚未被註釋掉。在python中有多個匹配和負面條件的多行正則表達式

更具體地說,我有以下的輸入...

maybe there is some text \THISTAG[arg1=1,argtwo]{WANT0} 
% \THISTAG[arg1=1,argtwo]{NOTWANT} 
% blah blah \THISTAG[arg1=1,argtwo]{NOTWANT} 
\THISTAG[arg1=1,argtwo]{WANT1}\THISTAG[arg1=1,argtwo]{WANT2}\\stuff 
\sometag{stuff I don't want}[{\THISTAG[arg1=1,argtwo]{WANT3}}]{more stuff I don't want} 
\THISTAG[arg1=1,argtwo]{OBV_WANT} 

我想下面的輸出

WANT0 
WANT1 
WANT2 
WANT3 
OBV_WANT 

到目前爲止,我有以下的代碼,不達到我想要的

with open(target, "r") as ins: 
    f = re.findall(r'^(?:[^%])?\\THISTAG\[.+\]{(.+?)}(?:{.+})?', ins.read(),re.MULTILINE) 
+0

你能告訴我們你得到了什麼呢? – sowrd299

+0

當然...我得到'OBV_WANT',沒有別的。 – Constantine

+1

病情不明確。我很難做出你想要的正則表達式。我可以得到所有的'WANT'和'OBV_WANT',但我也可以得到'NOTWANT'。請讓問題更清楚 –

回答

3

您可以通過符合過濾掉與%開始做那些正則表達式行:

import re 

res = [] 
with open('test.txt') as f: 
    res = sum([re.findall('\\THISTAG\[.*?\]{(.*?)}', line) 
       for line in f if not line.startswith('%') 
       ], []) 

    print res # ['WANT0', 'WANT1', 'WANT2', 'WANT3', 'OBV_WANT'] 
1

所以這裏是你的正則表達式縮短了一點點:

re.findall(r'\\THISTAG\[.+?\]{([^N].+?)}', a,re.MULTILINE) 

的重要組成部分,是在這裏:

{([^N].+?)} 

在那裏我有[^N]是你需要做你想要什麼,不想要你之間的區別。隨着你給的參數,我得到這樣的輸出:

>>> print(a) 
\THISTAG[arg1=1,argtwo]{WANT0} 
% \THISTAG[arg1=1,argtwo]{NOTWANT} 
% blah blah \THISTAG[arg1=1,argtwo]{NOTWANT} 
\THISTAG[arg1=1,argtwo]{WANT1}\THISTAG[arg1=1,argtwo]{WANT2}\stuff 
\sometag{stuff I don't want}[{\THISTAG[arg1=1,argtwo]{WANT3}}]{more stuff I don' t want} 
\THISTAG[arg1=1,argtwo]{OBV_WANT} 
>>> 
>>> re.findall(r'\\THISTAG\[.+?\]{([^N].+?)}', a,re.MULTILINE) 
['WANT0', 'WANT1', 'WANT2', 'WANT3', 'OBV_WANT'] 
+0

它確實按照您在答案中定義它的方式工作。但是,在閱讀實際文件時不起作用,評論不會被忽略。 – Constantine

+0

另外,我不明白你是如何讓它忽略頭兩個評論。 – Constantine

+0

啊,我很抱歉。我不明白「%」應該是一個評論。 niemmi的答案可能是你想要的最好的答案。你可以嘗試負向後視,但由於你沒有固定的長度,他們不會真正的工作。例如:re.findall(r'(?<!%)\\ THISTAG \ [。+?\] {(。+?)}',a,re.MULTILINE) – MikeTGW

2

試試這個

^%.*|\\THISTAG[^{]+{([^}]+)} 

Regex demo

說明:
^:字符串或行開始啓動依賴於多模式sample
.:任意字符除換行符sample
*:零次或多次sample
|:輪換/ OR操作數sample
\:轉義特殊字符sample
[^x]:一個字符不是x sample
+:一個或多個sample
(...)`:捕獲組sample

import re 
p = re.compile(ur'^%.*|\\THISTAG[^{]+{([^}]+)}', re.MULTILINE) 
test_str = u"maybe there is some text \THISTAG[arg1=1,argtwo]{WANT0}\n% \THISTAG[arg1=1,argtwo]{NOTWANT}\n% blah blah \THISTAG[arg1=1,argtwo]{NOTWANT}\n\THISTAG[arg1=1,argtwo]{WANT1}\THISTAG[arg1=1,argtwo]{WANT2}\\stuff\n\sometag{stuff I don't want}[{\THISTAG[arg1=1,argtwo]{WANT3}}]{more stuff I don't want}\n\THISTAG[arg1=1,argtwo]{OBV_WANT}" 

g = re.findall(p, test_str) 
for m in g: 
    if m: 
     print m 

輸出:

WANT0 
WANT1 
WANT2 
WANT3 
OBV_WANT 
+0

請問有更詳細的解釋嗎? – Constantine

+1

當我執行're.findall('(?:^ | \ G)(?!%)。*?\\ THISTAG [^ {] + {([^})時我無法返回'WANT2' ] +)}',ins.read(),re.MULTILINE)' – niemmi

+0

Python不支持'\ G',請參見[Regex demo](https://regex101.com/r/wJ5pI9/1#python)與Python的味道。 – niemmi