0

パーサーを使用せずにCSVファイルから行を引き離そうとしていますが、必要なのはphpを使用してコンマに基づいて文字列を分割することだけです。入力にコンマがない場合、これ自体はかなり簡単ですが、そうではありません。二重引用符で囲まれているコンマは無視したい。

最後の文を完全に無視して、問題自体を次のように変更することにしました。

二重引用符がない、または二重引用符のペアが散在しているコンマに基づいて文字列を分割したいと思います。

例:

text,"some,"chars,chars"more,""text",
    *     x      *          x       *

ここで、*は一致し、xは一致しません。

これは正規表現の能力を超えていますか?そうでない場合、この種の入力を処理できる正規表現はありますか?

4

2 に答える 2

1

これはもっとうまく書くことができると確信していますが、あなたのケースで機能するバリアントは次のとおりです。

 preg_match_all('/
     \s* ((?: (?=.|(?<=,)$) [^",]* | "(?: ""|[^"]* )+" )+) \s* (?:,|$) /xms',
     $line, $matches
 )
 and print_r($matches[1]);

ただし、他の一般的なCSVルールは尊重されません。私は通常\"、エスケープされた二重引用符であると期待します。また、引用符で囲まれた部分文字列と引用符で囲まれていない部分文字列の混合も非常に標準的ではありません。また、検証の形式がないため、正しくペアリングされていない場合でも、最後の見積もりを見落としてしまいます。

テスト文字列の場合:

        [0] => text
        [1] => "some,"chars
        [2] => chars"more,""text"
        [3] => 
于 2012-01-17T23:19:57.507 に答える
1

CSVファイルが正しい場合(各フィールドが「」で開始および終了するか、「」が含まれていない場合は、次のように再帰関数を使用して文字列を解析できます。

$csvString = 'zero,"o,ne",two,"thr,ee"';

function parseCsv($string, &$result)
{
    $regex = '/^((".*")|([^"].*))(,(.*))?$/U';
    $matches = array();
    preg_match($regex, $string, $matches);
    $result[] = $matches[1];
    if(isset($matches[5]))
    {
        parseCsv($matches[5], $result);
    }
}

$result = array();
parseCsv($csvString, $result);

var_dump($result);

これは、(エスケープされた)引用符を含む引用符付き文字列ではテストされていないことに注意してください。また、引用符で囲まれた文字列を引用符で囲みます。

上記の関数の結果は次のとおりです。

array
  0 => string 'zero' (length=4)
  1 => string '"o,ne"' (length=6)
  2 => string 'two' (length=3)
  3 => string '"thr,ee"' (length=8)
于 2012-01-17T23:25:14.760 に答える