我将从示例开始,因为它可能是最简单的解释。我们有一个多行文件:
...
STARTING LINE with something 83
...
STARTING LINE with other 12
...
ENDING LINE with yet another info
...
STARTING LINE with another 43
...
...
表示除STARTING LINE .*
和ENDING LINE .*
之外的任何内容(多行,包括空行)。
我们必须捕获包含所有不的所有STARTING LINE .*
,后跟ENDING LINE .*
的组,这意味着该示例中STARTING LINE .*
的第一个和最后一个出现。
单独STARTING LINE .*
和STARTING LINE .*...ENDING LINE .*
对出现的次数未知。
我尝试了多个具有正向和负向,向前和向后提前的表达式,但从未设法正确捕获出现的情况。
如果需要,我可以提供更多示例,但是可能很难向您提供我已经尝试过的表达式,因为我没有跟踪它们,而当前的表达式捕获了所有出现的事件,包括我们没有发现的事件想要
(^STARTING LINE .*?$)(?!^ENDING LINE)[.\n]+
(^STARTING LINE .*?$(?!.*^ENDING LINE)[.\n]*)
请注意,我们只希望一组中有STARTING LINE .*
行。
我们使用带有re.MULTILINE
标志(gm
)的Python 2.7正则表达式引擎。也尝试了其他re.DOTALL
(s
)选项,但均未成功。
答案 0 :(得分:1)
以下正则表达式在TCP_FASTOPEN_CONNECT
模式(demo)下对我有用:
MULTILINE
说明:
^STARTING LINE .+$\n(?!(?:(?!(?:STARTING|ENDING) LINE ).+\n)*ENDING LINE )
:起始行(由于^STARTING LINE .+\n
不需要$
)\n
:零个或多个中间线(由于(?:(?!(?:STARTING|ENDING) LINE ).+\n)*
不需要^
或$
)\n
:结尾行(由于先前的ENDING LINE
不需要^
) PS。假设您的换行确实是\n
,而不是\n
。
答案 1 :(得分:1)
您可以使用STARTING LINE
中的match,直到遇到换行符为止,然后STARTING LINE
再次使用正向超前。这样一来,您知道比赛之间至少有STARTING LINE
次。
对于最后一次匹配,您可以使用否定的超前查询来检查您是否不能再跟换行符(ENDING LINE
)。
^STARTING LINE(?:.*(?:(?!\n(STARTING|ENDING) LINE)\n.*)*(?=\nSTARTING LINE)|(?![\s\S]*\nENDING LINE)[\s\S]*$)
说明
^
行的开头STARTING LINE
字面上匹配(?:
启动非捕获组
.*
匹配0个以上的字符(?:
非捕获组
(?!
否定断言来断言右边的内容不是
\n(STARTING|ENDING) LINE
匹配换行符,后跟STARTING LINE或ENDING LINE )
关闭捕获组\n.*
匹配换行符和0个以上的字符)*
关闭负前瞻并重复0次以上(?=
肯定在右边的断言是
\nSTARTING LINE
匹配换行符,后跟STARTING LINE )
提前关闭|
或(?!
开始否定超前
[\s\S]*\nENDING LINE
匹配任意字符,包括换行符0次以上,后跟换行符和ENDING LINE )
近距离否定预测[\s\S]*$
匹配任意字符,包括换行符0次以上,直到字符串结尾)
关闭非捕获组答案 2 :(得分:0)
恐怕您需要通过流而不是单个正则表达式来解决它。像这样:
如果有帮助,请使用awk解决方案:
$ awk '/^STARTING LINE / { if ( startingline > "" ) { print(startingline); startingline=""; } else { startingline=$0; } } /^ENDING LINE / { startingline=""; } END { if ( startingline > "" ) print(startingline); }' file.txt
STARTING LINE with something 83
STARTING LINE with another 43