RegEx:拒绝复杂表达式的子部分

时间:2014-01-21 14:55:06

标签: regex notepad++

在下面的示例文本中,我希望匹配由\nI.*'定义的行开头的文本组(换行符和所有行),并且包括以\nA开头的后续行,仅当中间行中没有包含“BOM =”。即在示例中,我希望匹配第一个“设备”及其以下属性,但不匹配第二个设备,如我的注释中所示(#之后)。

I 657 device:THAT 2 1290 400 0 1 ' # Start matching here because no lines have "BOM="
A 1335 425 12 0 5 0 some text
A 1335 455 12 0 5 0 some text
A 1300 440 12 0 9 3 some text
A 1370 375 12 0 3 0 some text # Finish matching here
C 655 1 3 0
A 1370 450 12 0 3 3 #=2
C 740 2 4 0
A 1305 450 12 0 9 3 #=1
C 740 2 4 0
A 1305 450 12 0 9 3 #=1

I 318 device:THIS 2 300 1840 0 1 ' # Do not match again here because there's a line with "BOM="
A 320 1880 12 0 7 3 some text
A 320 1880 12 0 9 3 some text
A 380 1880 12 0 1 1 BOM=1,2
A 345 1865 12 0 5 0 some text
A 380 1830 12 0 3 0 some text 
C 666 1 3 0

在示例文本中,“某些文本”是电子设备的各种描述符,例如, “RATING = 63MW”,“REFDES = R123”。它可能包含空格但不包含换行符。

我得到的最远的是表达式

((\n|^)I((?!misc).)*?'\n)((A.*\n)*(A.*BOM=.*\n)(A.*\n)*)

与我想要的相反,即它找到包含BOM =的文本块。我想我可以通过将(A.*BOM=.*\n)更改为(?!(A.*BOM=.*\n))来改变这种情况,但这不起作用。

我希望在完成后在Notepad ++中使用它。

1 个答案:

答案 0 :(得分:3)

你可以试试这个正则表达式:

^I(?:(?!misc).)*'\n(?!(?:A.*\n)*?A.*BOM=)(?:A.*\n)*

regex101 demo

我添加了第三个块,其中BOM=位于以C开头的行上,其中匹配的设备因为BOM=与连续行开头不在同一行与A

默认情况下,Multiline匹配Notepad ++上的每一行,因此通常不需要(^|\n),但如果需要,可以还原它。

我还保留了(?:(?!misc).)*,因为你在表达式中有它,尽管它不需要对你的样本数据做任何事情。

(?!(?:A.*\n)*?A.*BOM=)是在行中有BOM=时匹配失败的原因。如果A.*BOM=在任意数量的(?:A.*\n)*?行之后(即以A开头的行)匹配,则这是一个负向前瞻,会阻止匹配。