在下面的示例文本中,我希望匹配由\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 ++中使用它。
答案 0 :(得分:3)
你可以试试这个正则表达式:
^I(?:(?!misc).)*'\n(?!(?:A.*\n)*?A.*BOM=)(?:A.*\n)*
我添加了第三个块,其中BOM=
位于以C
开头的行上,其中匹配的设备因为BOM=
与连续行开头不在同一行与A
。
默认情况下,Multiline匹配Notepad ++上的每一行,因此通常不需要(^|\n)
,但如果需要,可以还原它。
我还保留了(?:(?!misc).)*
,因为你在表达式中有它,尽管它不需要对你的样本数据做任何事情。
(?!(?:A.*\n)*?A.*BOM=)
是在行中有BOM=
时匹配失败的原因。如果A.*BOM=
在任意数量的(?:A.*\n)*?
行之后(即以A
开头的行)匹配,则这是一个负向前瞻,会阻止匹配。