需要正则表达式匹配多行,直到在常见分隔符之间找到匹配

时间:2016-05-12 06:20:44

标签: php regex powershell pattern-matching

我正在尝试编写一个将从日志文件返回多行匹配的正则表达式。使用下面的示例 - 我希望匹配整个'交易'以与日志中的所有其他事务(开始和结束)相同的文本开头和结尾。但是 - 在这些行之间有一个自定义标识符 - 在这种情况下是一个电子邮件地址,用于区分一个事务与另一个事务。

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模式。

2 个答案:

答案 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];

测试live on regex101.com

答案 1 :(得分:0)

使用s修饰符使.匹配换行符:

(?s)Start((?!Start).)*email1\@gmail\.com(.*?)End([^\n]*)

注意 ((?!Start).)*在我们通过*修饰符进入的每个位置断言否定前瞻,以确保我们是一次一个街区。

Live demo