我的问题很简单:我有一个文本文件,我处理并插入数据库中的所有数据,并为每个新行执行操作。问题是文本文件是我网关中收到的短信的日志,根据发送的文本,我会有一行对应每个短信。如果短信在其正文中没有任何新行,那么一切都没问题,另一方面,如果和SMS发送如下:
"Test
TestOnANewLine"
我每次都会得到一个破坏的日志文件和一个新行。样本如下:
2012-01-01 10:10:10,4C64DCD6.req,192.168.999.999,+12223334444,OK -- SMPP - 999.999.999.999:9999,SubmitUser=user;Sender=sender;SMSCMsgId=999999999;Text="Test1
NewLineTest
AnotherNEwLineTEst"
日志文件的解释如下:
date time, smsid, ip that processed it, number that is being sent to, status --connection type - ip that is sent from, user that submitted; sender name that is displayed; sms connection id; body of the sms
至于我使用PHP的语言和使用它的函数是一个简单的
foreach($lines as $line)
{ explode and do stuff }
我该如何处理这种情况?在这一点上任何帮助表示赞赏
提前致谢!!
答案 0 :(得分:2)
fgetcsv可以处理“''中包含的换行符,但在正文中有一个额外的”“字符会失败...
那么一些不负责任的regexp用法呢?
preg_match_all(#^(\d{4}-\d{2}-\d{2}[^,]+),([^,]+),([^,]+),([^,]+),([^,]+),SubmitUser=([^;])+;Sender=([^;])+;SMSCMsgId=([^;])+;Text="([\w\d\s\.\-,:;'"]+)"$#im', $file, $matches);
应该做的工作,因为不是太疯狂的文本,也许你应该把\ w \ d \ s .-,:;'“表达更多地满足你的需求
答案 1 :(得分:1)
在你可以解析日期之前,你不能循环换行吗? 也许考虑到前一行以双引号结尾?
我知道它不是万无一失但没有一些可识别的“消息结束”字符。这是我能想到的最好的:P
答案 2 :(得分:1)
尝试将所有日志条目规范化为每个日志条目的单个数组项(即将多个换行符中的条目组合成单个项)
$line_array = file('/path/to/file');
$log_array = array();
$i = -1;
$date_pattern = '/^[0-9]{4}-[0-9]{2}-[0-9]{2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}/';
foreach ($line_array as $line) {
if (1 === preg_match($date_pattern, $line)) {
// this is a new log entry
// let's trim the whitespace from the end of the last log array entry since we are done with it
if(isset($log_array[$i])) {
$log_array[$i] = rtrim($log_array[$i]);
}
// start a new log array entry
$i++;
$log_array[$i] = $line;
} else {
// this is not a new log entry
$log_array[$i] .= $line;
}
}
之后,您应该能够使用$log_array
来提取所需的数据。顺便提一下,当你循环遍历$log_array
时,我会注意到。首先提取msg文本可能会有所帮助。如果你在双引号上做一个贪婪的preg_match
,你就不应该在其中有引号的消息有任何问题,因为贪婪的匹配会找到最大可能的匹配字符串,在你的情况下,它将是引用邮件内容的引号。
答案 3 :(得分:1)
首先,感谢您提供的所有反馈,这非常宝贵,它帮助我解决了这个问题。此外,对于所有其他人来说,通过这篇文章并希望在这里找到解决方案是我的:
我改变了将/r/n
行的结尾从常规行解释为/r/n2
的方式,这意味着,当且仅当有常规新内容时,我会考虑读取文件中的新行第/r/n
行,在新的实体行上有2
(这是年初)
实际解决的部分是:
$data = file_get_contents($backup_file);
$lines=explode("\r\n2",$data);
foreach($lines as $line)
{
//explode and do stuff
}