1

私の問題は単純です。テキスト ファイルがあり、データベース内のすべてのデータを処理して挿入し、新しい行ごとにそれを処理します。問題は、テキスト ファイルがゲートウェイで受信した SMS のログであり、送信されるテキストによっては、各 SMS に対応する行があることです。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

改行から日付を解析できるようになるまで、改行をループできませんでしたか?前の行が二重引用符で終わっていることを考慮に入れてください。

私はそれがばかげた証拠ではないことを知っていますが、認識できる「メッセージの終わり」の文字がありません。これは私が考えることができる最高のものです:P

于 2012-09-06T16:21:22.147 に答える
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 に答える