Php 需要正则表达式匹配多行,直到找到公共分隔符之间的匹配
我正在尝试编写一个正则表达式,它将从日志文件返回多行匹配。使用下面的示例-我想匹配一个完整的“事务”,它以与日志开始和结束中的所有其他事务相同的文本开始和结束。但是,在这些行之间有一个自定义标识符,在本例中是一个电子邮件地址,它将区分一项交易和另一项交易Php 需要正则表达式匹配多行,直到找到公共分隔符之间的匹配,php,regex,powershell,pattern-matching,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. rando
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
基本上,我想说的是:从“开始”开始,匹配所有行,直到“结束”行,但仅当其中一行包含特定电子邮件地址时才返回匹配
现在-我的正则表达式将整个日志文件视为一个匹配项,因为第1行可能包含一个“开始”,第X行包含一个“结束”,在这两行之间的数百行中的某个地方-它们是电子邮件的匹配项。另外-应用程序是Powershell,如果有必要,将使用选择字符串模式。使用以确保您的正则表达式永远不会跨事务结束边界匹配:
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];
测试它。使用s修饰符进行修改。匹配换行符:
(?s)Start((?!Start).)*email1\@gmail\.com(.*?)End([^\n]*)
注:?!开始。*在我们通过*修饰符进入的每个位置断言一个负前瞻,以确保我们在同一时间处于一个块中
惰性量词不足以防止正则表达式跨越事务结束边界:@TimPietzcker这是因为您使用的是g修饰符,它必须尽最大努力。否。g修饰符意味着查找所有匹配项,而不仅仅是第一个匹配项。@TimPietzcker是的,你不应该这样做。OP说有一封标识符电子邮件,但您在提供的文本输入中复制了一个标识符。好的,我不确定从问题中是否总是有一个匹配-您很可能是对的,就是这种情况。但是,您的解决方案仍然存在OP描述的相同问题-如果您要查找的项目不是文件中的第一个项目,则正则表达式将匹配太多。这比我的第一句话更能说明我的观点。