1

ディスカッショングループでの活動は少しのんびりしているように見えるので、ここでPHPExcelユーザーを見つけたいと思っています:)。(私の元の投稿はここで見ることができます

CSVファイルの区切り文字やエンクロージャーを自動検出する機能をまとめました。
実行されたので、PHPExcelにプラグインしたいと思います(CSVクラスを拡張します)。
私の唯一の問題は、私のOOPスキルがかなり若いことであり、それを統合する方法/場所を見つけるのに少し問題があります。

私の関数は現在、を介して作成された配列を取りますが、file()必要に応じて簡単に変更できます。

function autoDetect(array $file, array $toDetect=array(true,false), $sampleSize=5){  

    $detectDelim = $toDetect[0]? true: false;
    $detectEncl = $toDetect[1]? true: false; 
    $sampleSize = ( count($file) < $sampleSize)? count($file): $sampleSize;  // set sample-size to the lesser value    
    array_splice($file, $sampleSize);  // trim down the array to only first X rows

    $delimiters = array(',','^','.',';',':',"\t"); // first elem will be the dflt
    $delimRegex = implode('',$delimiters);

    $enclosures = array('"',"'",'^'); // first elem will be the dflt
    $enclRegex = implode('',$enclosures);

    foreach ($file as $row) {
        $row=preg_replace( '/\r\n/', '', trim($row) );  // clean up .. strip new line and line return chars

        if($detectDelim){
            $stripped=preg_replace( "/[^$delimRegex]/", '', $row);  // clean up .. strip evthg x'ept dilim's
            $delimRowChars = str_split($stripped);  // get each char so we can inspect individually
            $delimCount = _count_instances($delimRowChars, $delimiters);  // TODO : fix how this overwrites itself
            // TODO : set delim
        }

        if($detectEncl){
            $stripped=preg_replace( "/[^$enclRegex]/", '', $row);  // clean up .. strip evthg x'ept dilim's
            $enclRowChars = str_split($stripped);  // get each char so we can inspect individually
            $enclCount = _count_instances($enclRowChars, $enclosures);  // TODO : fix how this overwrites itself
            // TODO : set encl
        }
    }

    echo'<pre>delims found in sample set: ', print_r($delimCount), '</pre>';  // For Testing ---->
    echo'<pre>encls found in sample set: ', print_r($enclCount), '</pre>';  // For Testing ---->
    echo "<pre>Suggested Delimiter: '",_array_max($delimCount),"' </pre>";  // For Testing ---->    
    echo "<pre>Suggested Enclosure: '",_array_max($enclCount),"' </pre>";  // For Testing ---->

    //return TODO ;        
}


/**
 * 
 */
function _count_instances(array $haystacks, array $needles, $maxOnly = false){
    $basket = array();  // instantiate
    foreach ($haystacks as $haystack) {
        foreach ($needles as $needle) {  // this throws an undef'd index err and adds an element to the array
            if( strpos($haystack, $needle) !== false) {  // if the needle is in the haystack ...
                if($needle == "\t") $needle = '\t';  // TODO : decouple this from "\t" so it can work for other chars too
                $basket[$needle]++;  // ... increment
            }
        }
    }
    if($maxOnly) $basket = _array_max($basket);
    return $basket;
}

/**
 * 
 */
function _array_max(array $target){
    $target = array_keys($target, max($target));
    $target = $target[0];
    return $target;
}

ファイルが解析される前に自動検出器を実行する必要がありますが、オブジェクトに情報が表示されません。
いつ/どこで/どのように接続する必要がありますか?origファイルへのアクセスはありますか?

4

1 に答える 1

1

PHPExcelコミュニティが応答を提供することになったので、後世のためにここでそれをシャーリングすると思いました:
)OPの上部にあるリンクからも確認できます。

「この自動検出器の呼び出しをPHPExcel/Reader / CSV.phpファイルのloadIntoExistingメソッドに入れる必要がありますが、スクリプトはすべての行をメモリにロードするのではなく、一度に1行ずつCSVを読み取ります(十分なメモリがあります)論理的には、BOMのチェックの直後に数行をロードし、$ this-> _ delimiter値を設定してから、ファイルを巻き戻すことを忘れないでください。」

それが他の誰かを助けることができることを願っています。

于 2012-07-12T19:43:48.230 に答える