You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用正则表达式从日志字符串中提取用户名与消息?

提取日志中的用户名和消息内容

嘿,既然你已经搞定了日期的提取,那咱们直接把正则整合一下,一次性把日期、用户名和消息都抓出来,效率更高~

首先分析你的日志格式:每条日志都是[日期时间] 用户名: 消息内容的结构,消息里可能包含空格、表情符号,直到下一条日志的[开头或者字符串结束。

完整正则表达式

咱们用一个正则就能捕获所有需要的内容:

/\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] ([^:]+): (.*?)(?=\s*\[|$)/

正则各部分解释

  • \[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\]:匹配带方括号的完整日期时间,把时间部分捕获到第1组(和你之前的提取逻辑一致)
  • ([^:]+):匹配用户名——因为用户名后面紧跟冒号,所以用[^:]+匹配所有不是冒号的字符,捕获到第2组(如果用户名里可能有冒号,那得调整,但你的示例里没有,这个逻辑完全够用)
  • : (.*?)(?=\s*\[|$):匹配冒号+空格后的消息内容:
    • .*?是非贪婪匹配,避免把后面的日志内容也包含进来
    • (?=\s*\[|$)是正向预查,告诉正则“匹配到下一个[(前面可能有空格)或者字符串结尾就停止”,完美分割每条消息

PHP代码示例

因为你的日志是多条连在一起的,用preg_match_all可以一次性提取所有条目:

$log = "[2017-03-14 11:48:22] Steve T: Hi! [2017-03-14 11:49:01] Oscar: Hi! :D How are u doin? [2017-03-14 11:50:24] Steve T: Im doing great :P";

// 用PREG_SET_ORDER让每个日志条目单独成一个数组,方便遍历
preg_match_all('/\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] ([^:]+): (.*?)(?=\s*\[|$)/', $log, $matches, PREG_SET_ORDER);

// 遍历输出结果
foreach ($matches as $entry) {
    $datetime = $entry[1];
    $username = trim($entry[2]); // 去掉用户名可能带的前后空格
    $message = $entry[3];
    
    echo "时间:{$datetime}\n用户名:{$username}\n消息:{$message}\n\n";
}

运行这段代码后,输出会是:

时间:2017-03-14 11:48:22
用户名:Steve T
消息:Hi!

时间:2017-03-14 11:49:01
用户名:Oscar
消息:Hi! :D How are u doin?

时间:2017-03-14 11:50:24
用户名:Steve T
消息:Im doing great :P

如果只是想单独提取用户名和消息(不需要日期),也可以把正则简化成:

/\[.*?\] ([^:]+): (.*?)(?=\s*\[|$)/

这样第1组是用户名,第2组是消息内容。

内容的提问来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:46:04