日本語

データとスプレッドシート · CSV クリーナー

CSV パーサーがフィールド内の引用符、埋め込みカンマ、改行を処理する方法

· 仕組み

csv 解析中 データ形式

引用符で囲まれたコンマ、二重引用符、およびフィールド内に埋め込まれた改行を保持するパーサー状態パス
オリジナル ToolAcre ベクトル イラスト

カンマによる分割は、フィールドにカンマ、引用符、または改行が含まれるまで機能します。この投稿では、実際の CSV パーサーが使用する小さなステート マシン、引用ルールが存在する理由、および引用が壊れた場合の修復ツールの動作について説明します。

カンマを含むアドレス フィールドが列ごとに右にシフトされている - 単純な分割では解析されない理由

カンマごとに行を分割すると、住所、メモ、または製品説明にその文字が含まれるとすぐに失敗します。セパレータは、パーサーが引用符で囲まれたフィールドの外側にある場合にのみフィールドを終了します。引用符内では、同じバイトが値に属し、変更されずにプレビューに到達する必要があります。

ToolAcre は、CSV が単純なテキストであると仮定するのではなく、テストによってこれを証明します。引用符内にカンマが含まれるセミコロン ファイルは、長方形の形状がスコア付けされる前に各候補が行に解析されるため、依然としてセミコロン区切りとして検出されます。生の句読点の数が方言を決定することはありません。

引用符の規則 — 区切り文字、引用符、または改行を含むフィールドは二重引用符で囲まれ、内側の引用符は二重になります。

選択した区切り文字、二重引用符、改行、または復帰を含むフィールドは、シリアル化中に引用符で囲まれます。引用符で囲まれたフィールド内のリテラルの二重引用符は、隣接する 2 つの引用符で表されます。解析すると、そのペアはセルに 1 つの引用符を提供し、フィールドを閉じません。

引用符は、それ以外の場合は空のフィールドの先頭に表示される場合にのみ、引用符で囲まれた状態を開きます。 12" パイプなどの引用符で囲まれていない値では、引用符はリテラル データのままです。その実装の選択はテストされ、テキストの途中にある測定マークが後続の列を飲み込むのを防ぎます。

ステート マシンとしてのパーサー — 内側の引用符と外側の引用符、および一度に 1 文字ずつフィールドの終了位置を決定する方法

コア ループは、現在のフィールド、現在の行、および `inQuotes` 状態を追跡します。引用符の外側では、区切り文字がフィールドをプッシュし、CR、LF、または CRLF が行をプッシュします。引用符の内側には、エスケープされたペアを形成するか引用符で囲まれた状態を終了する引用符を除くすべての文字が追加されます。

この 1 文字の進行は、単純な正規表現や行分割が脆弱である理由を説明します。改行でレコードが終了するかどうかは前の入力に依存し、引用符でフィールドを閉じるかどうかは次の引用符に依存します。パーサーは、文字列を通じてその最小限の状態を正確に伝えます。

埋め込み改行 — 行が複数行にまたがる理由と、grep や wc などの行ベースのツールがレコードをカウントしない理由

引用符で囲まれたフィールドには LF、CRLF、または単独の CR が含まれる場合があり、それらの文字は値の中に残ります。したがって、1 つの論理レコードがテキスト エディターで複数の表示行を占める場合があります。行指向のコマンドで物理行をカウントしても、必ずしもデータ行がカウントされるわけではありません。

終了引用符の後に、次の区切り文字またはレコード終了が構造的な意味を再開します。 ToolAcre のテストは、埋め込み LF と埋め込み CRLF の両方をアサートし、1 行のみが生成されたことを検証します。この動作は RFC ラベルから推測されるものではありません。これは、出荷された状態マシンによって直接実行されます。

壊れた引用 — ファイルの残りの部分を飲み込むアンバランスな引用、および修復ツールがフィールドを一貫して再引用する方法

アウトラインでは見積もりの修正を約束していましたが、閉じられていない見積もりは本質的に曖昧です。 ToolAcre は、引用符で囲まれた状態が開始された行に対して `UNCLOSED_QUOTE` を報告し、その後のすべてを 1 つのフィールドに読み取ります。クロージングポジションを作成したり、意図したレコードを再引用したりすることはありません。

この保守的な失敗により、消費されたテキストが検査用に保存され、後の引用符または改行がデータとして意図されたものであるかどうかを知っているふりをすることがなくなります。ソースを修正するかエクスポートを再生成してから、リロードしてください。シリアル化により、正常に解析されたテーブルを正規化できます。不正なソースによって認識不能になった行境界を回復することはできません。

壊れた引用は報告されていますが、修復されていません。閉じられていないフィールドは残りのテキストを消費します

`name,note` をヘッダーとして使用し、次に Ada とカンマと改行を含むメモを含む 1 行と、メモが `She said "hi"` である別の行を使用します。ソース CSV で、長いメモを引用し、内側の引用符を `""hi""` と記述します。パーサーは 2 つのデータ行を返し、両方の特殊文字を保持します。

引用符を最小限に抑えてシリアル化する場合、プレーン名には引用符は必要ありませんが、メモ フィールドには構造文字が含まれるため引用符が付けられます。その出力を再度解析すると、冗長なソース引用符が消えた場合でも、同じヘッダーとセルが得られます。このラウンド トリップは、バイトごとのスタイル設定ではなく、データの同等性によって定義されます。

これでカバーされないもの — バックスラッシュエスケープを使用する方言、および引用時の意図を推測するためのヒューリスティックは非常に曖昧です

バックスラッシュエスケープ方言はパーサーの外にあります。ここでは、引用符の前のバックスラッシュには特別なステートマシンの意味はありません。引用符は二重引用符の規則に従って解釈されますが、テキストのままです。また、このツールは、冒頭の引用符が一致しないままになると、意図を推測することも拒否します。

これらの境界は、別のエスケープ規則に設定されたデータベース ダンプをインポートするときに重要になります。ロードする前にプロデューサーの方言を特定するか、RFC スタイルの引用符を使用してエクスポートします。いくつかの互換性のないエスケープ ルールを黙って認識するパーサーは、リテラルのバックスラッシュを制御構文に変換し、不一致を隠すことができます。

引用符を尊重し、行はそのままの状態を維持します — ToolAcre CSV Cleaner の引用符修復により、標準パーサーが正しく読み取るファイルを生成する方法

引用符で囲まれた状態を尊重すると、区切り文字とレコードの終わりがそれらが属するセル内に保持されます。 ToolAcre は 3 つの行末フォームも処理し、先頭の UTF-8 BOM を削除し、行幅の不一致を報告します。これらの動作は、検索と置換のトリックの集合ではなく、1 つの構造読み取りの独立した部分です。

有効な解析の後、シリアル化は埋め込まれた引用符を 2 倍にし、保護が必要なフィールドをすべて引用符で囲み、デフォルトで CRLF 出力を使用します。無効な閉じられていない引用の後は、停止してソース証拠から修復します。このツールは既知のセルを標準化できます。未知のテーブルを再構築するとは主張しません。