php - 使用正则表达式将日志条目解析为多个部分

标签 php regex

我这里有这行文本,它总是相同的(除了末尾的消息):

2021-12-08T18:18:38+00:00 INFO Produktbestand erfolgreich von Collmex abgerufen | "STOCK_AVAILABLE;23;1;363;PCE;-1\r\nMESSAGE;S;204020;Daten?bertragung erfolgreich. Es wurden 1 Datens?tze verarbeitet.\r\n"

我有 3 个函数应该返回部分日志条目:

public function get_log_file_entry_time( string $entry ): string {
    
}

public function get_log_file_entry_level( string $entry ): string {

}

public function get_log_file_entry_message( string $entry ): string {

}

我首先尝试使用带有空格作为分隔符的 explode,这种方法有效但不是最好的方法,因为在某些情况下日志消息可能会很长。

我不是 RegEx 专家,但我发现以下组合可以匹配前两部分:([^\s]+) ([A-Z]+)

这会返回时间戳和级别。现在我很难在第二组之后得到消息——也许我的嵌套根本不完美。任何建议都会让我开心!

注意

消息将在日志级别后的第一个空格后开始。例如:

Produktbestand erfolgreich von Collmex abgerufen | "STOCK_AVAILABLE;23;1;363;PCE;-1\r\nMESSAGE;S;204020;Daten?bertragung erfolgreich. Es wurden 1 Datens?tze verarbeitet.\r\n"

最佳答案

您可以使用 3 个捕获组,其中第 3 个组包含该行的其余部分,后面是所有不以日期时间(如模式)开头的行。

您可以使第 1 组的模式更具体一些,并匹配不以第 1 组模式开头的其余行,您可以使用 (?1)< 递归第一个子模式

^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+\d{2}:\d{2})\h+([A-Z]+)\h+(.*(?:\R(?!(?1)).*)*)

在部分中,模式匹配:

  • ^ 字符串开始
  • (\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+\d{2}:\d{2}) 捕获group 1,匹配日期和时间类模式
  • \h+ 匹配 1+ 个水平空白字符
  • ([A-Z]+) 捕获第2组,匹配1+个大写字符A-Z
  • \h+ 匹配 1+ 个水平空白字符
  • ( 捕获组 3
    • .* 匹配剩余部分
    • (?:\R(?!(?1)).*)* 可选地重复匹配一个换行符和该行的其余部分断言当前位置的右边是什么不匹配子模式 1(模式组 1)
  • ) 关闭组 3

查看 regex demo和一个 PHP demo .

例如有 2 行,都以相同的模式开始:

$re = '/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+\d{2}:\d{2})\h+([A-Z]+)\h+(.*(?:\R(?!(?1)).*)*)/m';
$str = '2021-12-08T18:18:38+00:00 INFO Produktbestand erfolgreich von Collmex abgerufen | "STOCK_AVAILABLE;23;1;363;PCE;-1
MESSAGE;S;204020;Daten?bertragung erfolgreich. Es wurden 1 Datens?tze verarbeitet.
"
2021-12-08T18:18:38+00:00 INFO Produktbestand erfolgreich von Collmex abgerufen | "STOCK_AVAILABLE;23;1;363;PCE;-1
MESSAGE;S;204020;Daten?bertragung erfolgreich. Es wurden 1 Datens?tze verarbeitet.
"';

preg_match_all($re, $str, $matches, PREG_SET_ORDER);

foreach ($matches as $match) {
    print_r($match);
}

输出

Array
(
    [0] => 2021-12-08T18:18:38+00:00 INFO Produktbestand erfolgreich von Collmex abgerufen | "STOCK_AVAILABLE;23;1;363;PCE;-1
MESSAGE;S;204020;Daten?bertragung erfolgreich. Es wurden 1 Datens?tze verarbeitet.
"
    [1] => 2021-12-08T18:18:38+00:00
    [2] => INFO
    [3] => Produktbestand erfolgreich von Collmex abgerufen | "STOCK_AVAILABLE;23;1;363;PCE;-1
MESSAGE;S;204020;Daten?bertragung erfolgreich. Es wurden 1 Datens?tze verarbeitet.
"
)
Array
(
    [0] => 2021-12-08T18:18:38+00:00 INFO Produktbestand erfolgreich von Collmex abgerufen | "STOCK_AVAILABLE;23;1;363;PCE;-1
MESSAGE;S;204020;Daten?bertragung erfolgreich. Es wurden 1 Datens?tze verarbeitet.
"
    [1] => 2021-12-08T18:18:38+00:00
    [2] => INFO
    [3] => Produktbestand erfolgreich von Collmex abgerufen | "STOCK_AVAILABLE;23;1;363;PCE;-1
MESSAGE;S;204020;Daten?bertragung erfolgreich. Es wurden 1 Datens?tze verarbeitet.
"
)

关于php - 使用正则表达式将日志条目解析为多个部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70282355/

相关文章:

php - PDO Sqlite 一般错误 : 25 bind or column index out of range

javascript - 加入/连接的动态下拉菜单

Java:如何用一个替换多个回车?

ios - 正则表达式不允许字符串 swift ios 中出现空格

objective-c - 静态 NSRegularExpression 始终为零

mysql - mysql扩展名已弃用,以后将删除:使用mysqli或PDO代替

php - 查询中的 kohana 引号

php类别,子类别树

location.hash 的 Javascript 正则表达式匹配

c# - 正则表达式查找以特定字符开头的单词