我正在尝试编写一个将从日志文件返回多行匹配的正则表达式。使用下面的示例 - 我希望匹配整个'交易'以与日志中的所有其他事务(开始和结束)相同的文本开头和结尾。但是 - 在这些行之间有一个自定义标识符 - 在这种情况下是一个电子邮件地址,用于区分一个事务与另一个事务。
Start of a transaction.
random line 1.
random line 2.
email1@gmail.com
End of a transaction.
Start of a transaction.
random line 1.
random line 2.
email1@yahoo.com
random line 3.
End of a transaction.
以下是我的开始:
^Start(.*?)\n(((.*?)(email1\@gmail\.com)(.*?)|(.*?))\n){1,}End (.*?)\n
基本上 - 我想说:开始'开始' - 并匹配所有行,直到'结束' line,但只有在其中一行包含特定电子邮件地址时才返回匹配。
现在 - 我的正则表达式将整个日志文件视为单个匹配,因为大概第1行包含一个'开始'和X行包含一个' End'介于两者之间的数百行 - 他们是电子邮件的匹配。此外 - 应用程序是Powershell,如果重要的话,将使用Select-String模式。
答案 0 :(得分:2)
使用negative lookahead assertion确保您的正则表达式在“交易结束”边界内永远不会匹配:
preg_match_all(
'/^ # Start of line
Start\ of\ a\ transaction\. # Match starting tag.
(?: # Start capturing group.
(?!End\ of\ a\ transaction) # Only match if we\'re not at the end of a tag.
. # Match any character
)* # any number of times.
email1@gmail\.com # Match the required email address
(?:(?!End\ of\ a\ transaction).)* # and the rest of the tag.
^ # Then match (at the start of a line)
End\ of\ a\ transaction\.\n # the closing tag./smx',
$subject, $result, PREG_PATTERN_ORDER);
$result = $result[0];
答案 1 :(得分:0)
使用s
修饰符使.
匹配换行符:
(?s)Start((?!Start).)*email1\@gmail\.com(.*?)End([^\n]*)
注意 :((?!Start).)*
在我们通过*
修饰符进入的每个位置断言否定前瞻,以确保我们是一次一个街区。