Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 需要正则表达式匹配多行,直到找到公共分隔符之间的匹配_Php_Regex_Powershell_Pattern Matching - Fatal编程技术网

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描述的相同问题-如果您要查找的项目不是文件中的第一个项目,则正则表达式将匹配太多。这比我的第一句话更能说明我的观点。