两种模式之间的PHP正则表达式匹配
我试图解析一个包含许多跟踪的日志文件,其中一些跟踪有多行 例如:两种模式之间的PHP正则表达式匹配,php,regex,Php,Regex,我试图解析一个包含许多跟踪的日志文件,其中一些跟踪有多行 例如: [trace-123] <request>This is a log line</request> [trace-124] <reply>This is another log line this is part of "[trace-124]" still.</reply> [trace-125] <request>final log line.</reques
[trace-123] <request>This is a log line</request>
[trace-124] <reply>This is another log line
this is part of "[trace-124]" still.</reply>
[trace-125] <request>final log line.</request>
找到从那场比赛到下一场比赛的一切
我发现
#\[trace-[0-9]*+\](.|\s)*#
工作得很好,但当有换行符时会出现故障 符号
表示除换行符以外的每个字符\n
,您可以尝试使用(.|\s)
以以下方式更改它:
#\[trace-[0-9]*+\].*#s
注意:您可以使用非capturant括号(?:)
Easyer,添加标志“s”
你应该使用不情愿的量词(
?
,+?
或*?
)
我相信这个regex/(\[trace-[0-9]*\]\s*(?m:.*)/
应该可以做到这一点。。。(?m:.*?
部分是秘密。:) 使用以下命令:
preg_split('/\R+(?=\[trace-\d+])/', $str)
$file='[trace-123]这是一个日志行
[trace-124]这是另一个日志行
这仍然是“[trace-124]”的一部分。
[trace-125]最终记录线';
$tracePattern=“/\[trace-[0-9]*+\]+\s*.*?/s”;
preg_match_all($tracePattern、$file、$line);
$lines=$lines[0];//默认情况下,$lines[0]将是一个匹配数组,所以获取该数组
回声“;打印(行);回声“;
工作演示:我建议通过
preg\u split
(\[trace-[0-9]+\].*?<\/(?:reply|request)>)
这将导致以下结果
$results = preg_split('/\R(?=\[trace[^\]]*\])/', $text);
print_r($results);
数组
(
[0]=>[trace-123]这是一条日志行
[1] =>[trace-124]这是另一个日志行
这仍然是“[trace-124]”的一部分。
[2] =>[trace-125]最终日志行。
)
这应该与以下位置上的标志s
有关:
Array
(
[0] => [trace-123] <request>This is a log line</request>
[1] => [trace-124] <reply>This is another log line
this is part of "[trace-124]" still.</reply>
[2] => [trace-125] <request>final log line.</request>
)
(\[trace-[0-9]+\].*
以下可能是更好的方法
# ^[^\S\n]*(\[trace-[^]]*\][^\n]*(?:(?!\s+\[trace-[^]]*\])\n[^\n]*)*)
^ [^\S\n]*
(
\[trace- [^]]* \] [^\n]*
(?:
(?! \s+ \[trace- [^]]* \] )
\n [^\n]*
)*
)
看
输出
'[trace-123] <request>This is a log line</request>'
'[trace-124] <reply>This is another log line
this is part of "[trace-124]" still.</reply>'
'[trace-125] <request>final log line.</request>'
数组
(
[0]=>[trace-123]这是一条日志行
[1] =>[trace-124]这是另一个日志行
这仍然是“[trace-124]”的一部分。
[2] =>[trace-125]最终日志行。
)
这在多行模式下工作。修剪前导空格和尾随换行符
编辑:假设锚点是[trace-]
,并且位于行或开头加上非换行空格,直到“trace”。这是
只有可识别的记录分隔符 输出(单引号)
“[trace-123]这是一条日志行”
“[trace-124]这是另一个日志行
这是“[trace-124]”的一部分
“[trace-125]最终日志行。”
不需要,他可以添加模式修饰符s
(PCRE\u DOTALL)。我不明白为什么你所做的需要正则表达式。您只需在文件的每一行中循环查找字符串开头的[trace-
。每次遇到此值时,请开始将这些行添加到正在构建的数组中下一个数组位置的字符串中。下次遇到以开头的另一行时,请停止添加到此字符串[trace-
或下次遇到以其他非跟踪签名开头的行时(例如,如果您有[error-
或其他行)。要继续我的评论…需要多行正则表达式可能需要将整个日志文件放入内存中(在看到下一个[trace-
之前,或者至少将其部分存储到内存中,这基本上需要执行我上面建议的实现)。这对于较大的日志文件可能不可行。您可能应该专注于一种解决方案,该解决方案允许您一次解析和处理一行。@Mike-如果文件太大,则使用多gig ram容量。逐行读取可能需要较长的时间,并且构建阵列也必须卸载。另一种方法是一次读取10000行,用多行正则表达式处理记录,捕获最后一个记录开始,放在缓冲区前面,再读取10000行(或者,像10兆),重复。@sin True,但通常情况下,您需要一个对RAM要求很低的进程,因为服务器可能会承担生产负载。在这种情况下,您无法将大量RAM专用于单个进程。您是对的,构建阵列在RAM上也可能太贵,这取决于此trac所在的总行数e数据是存在的。@Mike-是的,这是真的,但在服务器环境中,每个虚拟机可能有一个gig或两个虚拟ram。但是,在分区驱动器上逐行执行这项操作需要大量磁盘。读取10兆数据块和使用多行正则表达式在资源方面是一个很好的平衡。简单地说,这至少是f的10倍或更多倍阿斯特。
Array
(
[0] => [trace-123] <request>This is a log line</request>
[1] => [trace-124] <reply>This is another log line
this is part of "[trace-124]" still.</reply>
[2] => [trace-125] <request>final log line.</request>
)
(\[trace-[0-9]+\].*?<\/(?:reply|request)>)
$results = preg_split('/\R(?=\[trace[^\]]*\])/', $text);
print_r($results);
Array
(
[0] => [trace-123] <request>This is a log line</request>
[1] => [trace-124] <reply>This is another log line
this is part of "[trace-124]" still.</reply>
[2] => [trace-125] <request>final log line.</request>
)
# ^[^\S\n]*(\[trace-[^]]*\][^\n]*(?:(?!\s+\[trace-[^]]*\])\n[^\n]*)*)
^ [^\S\n]*
(
\[trace- [^]]* \] [^\n]*
(?:
(?! \s+ \[trace- [^]]* \] )
\n [^\n]*
)*
)
'[trace-123] <request>This is a log line</request>'
'[trace-124] <reply>This is another log line
this is part of "[trace-124]" still.</reply>'
'[trace-125] <request>final log line.</request>'