简体   繁体   English

需要正则表达式匹配多行,直到在公共定界符之间找到匹配项

[英]Need Regex to match multiple lines until Match is found between common delimiters

I am attempting to write a regex that will return a multiple line match from a log file. 我试图编写一个正则表达式,它将从日志文件返回多行匹配。 Using the sample below -- I want to match an entire 'transaction' which begins and ends with the same text as ALL other transactions in the log (Start and End). 使用下面的示例-我想匹配一个完整的“事务”,该事务以与日志中所有其他事务(“开始”和“结束”)相同的文本开始和结束。 However - between those lines there is a custom identifier -- in this case an email address that will differentiate one transaction from another. 但是-在这些行之间有一个自定义标识符-在这种情况下,这是一个电子邮件地址,可将一项交易与另一项交易区分开。

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.

Here is what I am starting with: 这是我开始的内容:

^Start(.*?)\n(((.*?)(email1\@gmail\.com)(.*?)|(.*?))\n){1,}End (.*?)\n

Essentially - I want to say: Begin with 'Start' -- and match all lines until an 'End' line, but only return a match if one of the lines contains a particular email address. 本质上-我想说:以'开始'开头-匹配所有行,直到'结束'行,但仅当其中一行包含特定的电子邮件地址时才返回匹配项。

Right now -- my regex treats the entire log file as a single match since presumably line 1 contains a 'Start' and line X contains an 'End' and somewhere in the hundreds of lines in between -- their is a match for the email. 现在-我的正则表达式将整个日志文件视为一个单独的匹配项,因为大概第1行包含一个“开始”,第X行包含一个“结束”,并且介于两者之间的几百行中-它们是电子邮件的匹配项。 Also -- application is Powershell and will be using a Select-String pattern, if that matters. 另外-应用程序是Powershell,并且如果需要的话,将使用Select-String模式。

Use a negative lookahead assertion to make sure your regex never matches across an "End of transaction" boundary: 使用否定的前瞻性断言来确保您的正则表达式在“交易结束”边界内永不匹配:

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

Test it live on regex101.com . 在regex101.com上进行实时测试。

Use s modifier to make . 使用s修饰符进行制作. match newline characters: 匹配换行符:

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

Note : ((?!Start).)* asserts a negative lookahead at each position which we stepped into by * modifier to ensure that we are in one block at a single time. 注意 ((?!Start).)* ?! ((?!Start).)*在我们通过*修饰符进入的每个位置断言一个负前行,以确保我们一次处于一个块中。

Live demo 现场演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM