1

我的问题很简单:我有一个文本文件,我处理并插入数据库中的所有数据,并为每个新行处理它。问题是文本文件是在我的网关中接收到的短信的日志,并且根据正在发送的文本,我将有一行对应于每个短信。如果 SMS 在其正文中没有任何新行,则一切正常,另一方面,如果 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   }

我该如何处理这种情况?在这一点上,任何帮助表示赞赏

提前致谢!!

4

4 回答 4

2

fgetcsv可以处理包含在 '"' 中的换行符,但是在正文中添加一个额外的 '"' 字符会失败......

那么一些不负责任的正则表达式使用呢?

preg_match_all(#^(\d{4}-\d{2}-\d{2}[^,]+),([^,]+),([^,]+),([^,]+),([^,]+),SubmitUser=([^;])+;Sender=([^;])+;SMSCMsgId=([^;])+;Text="([\w\d\s\.\-,:;'"]+)"$#im', $file, $matches);

应该做的工作,不是太疯狂的文本,也许你应该把 \w\d\s.-,:;'" 表达更多地满足你的需要

于 2012-09-06T16:56:11.623 回答
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
}
于 2012-09-07T17:53:39.617 回答
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. 首先提取味精文本可能会有所帮助。如果您preg_match对双引号进行了贪婪,那么在其中包含引号的消息应该没有任何问题,因为贪婪匹配会找到最大可能的匹配字符串,在您的情况下,这将是限制消息内容的引号之间的所有内容.

于 2012-09-06T16:36:09.057 回答
1

在可以从中解析日期之前,您不能循环遍历换行符吗?也许考虑到前一行以双引号结尾?

我知道它不是万无一失的,但没有一些可识别的“消息结束”字符。这是我能想到的最好的:P

于 2012-09-06T16:21:22.147 回答