あなたをぞっとさせるようなコーディング上の理由から (恥ずかしくて言えません)、1 つの文字列に多数のテキスト項目を格納する必要があります。
文字で区切ります。
これにはどの文字を使用するのが最適ですか。つまり、テキストに表示される可能性が最も低い文字はどれですか? ロケールの問題を避けるために、印刷可能で、おそらく ASCII で 128 未満でなければなりません。
「単位区切り」の ASCII コード「US」を選択します: ASCII 31 (0x1F)
昔は、ほとんどのことはランダム アクセスなしで連続的に行われていました。これは、いくつかの制御コードが ASCII に埋め込まれていることを意味します。
ASCII 28 (0x1C) File Separator - Used to indicate separation between files on a data input stream.
ASCII 29 (0x1D) Group Separator - Used to indicate separation between tables on a data input stream (called groups back then).
ASCII 30 (0x1E) Record Separator - Used to indicate separation between records within a table (within a group). These roughly map to a tuple in modern nomenclature.
ASCII 31 (0x1F) Unit Separator - Used to indicate separation between units within a record. The roughly map to fields in modern nomenclature.
単位区切りは ASCII であり、それを表示するための Unicode サポートがあります (通常、同じグリフ内の「us」)。ただし、多くのフォントでは表示されません。
表示する必要がある場合は、フィールドに解析された後、アプリケーション内で表示することをお勧めします。
なんらかの恥ずかしい理由でCSVを使用できないと仮定すると、データを使用すると思います。いくつかのサンプルデータを取得し、0〜127の値ごとに単純な文字カウントを実行します。発生しないものを1つ選択してください。選択肢が多すぎる場合は、より大きなデータセットを取得してください。書くのにそれほど時間はかからず、あなたはあなたに最適な答えを得るでしょう。
問題のドメインごとに答えが異なるため、| (パイプ)はシェルスクリプトで一般的であり、^は数式で一般的であり、他のほとんどの文字にも同じことが当てはまる可能性があります。
私は個人的に私が行くと思います| (パイプ)選択肢が与えられたとしても、実際のデータを使用するのが最も安全です。
そして、あなたが何をするにしても、あなたが脱出計画を立てたことを確認してください!
異なる言語を使用する場合、この記号: ¬
最高であることが証明されました。しかし、私はまだテスト中です。
おそらく| または ^ または ~ 2 つの文字を組み合わせることもできます
「印刷可能」と言いましたが、タブ (0x09) やフォーム フィード (0x0c) などの文字を含めることができます。コンマはテキストに表示される場合があるため、区切りファイルには、ほとんどの場合、コンマではなくタブを選択します。
(興味深いことに、ASCII テーブルには、GS (0x1D)、RS (0x1E)、および US (0x1F) という文字があり、グループ、レコード、および単位の区切り記号があり、それらが何であれ、あります。)
「印刷可能」とは、ユーザーが認識して簡単に入力できる文字を意味する場合、パイプ | を使用します。可能性として、他のいくつかの奇妙な文字(@
または~
、^
または\
、またはここでは入力できないバッククォート)を使用して、シンボルを最初に入力します。これらの文字+=!$%&*()-'":;<>,.?/
は、ユーザー入力で発生する可能性が高いようです。アンダースコア_
とハッシュ#
とブラケット{}[]
についてはわかりません。
CSV スタイルのフォーマットを使用するのはどうですか。文字は標準の CSV 形式でエスケープできます。すでに多くのパーサーが作成されています。
高速エスケープのために、私は次のようなものを使用します: str1、str2、および str3 を連結したいとします。
delimitedStr=str1.Replace("@","@a").Replace("|","@p")+"|"+str2.Replace("@","@a").Replace("|","@p")+"|"+str3.Replace("@","@a").Replace("|","@p");
次に、元の使用を取得するには:
splitStr=delimitedStr.Split("|".ToCharArray());
str1=splitStr[0].Replace("@p","|").Replace("@a","@");
str2=splitStr[1].Replace("@p","|").Replace("@a","@");
str3=splitStr[2].Replace("@p","|").Replace("@a","@");
注: 置換の順序は重要です
壊れにくく、実装が簡単
パイプ記号を使用できますか? これは通常、コンマまたはタブで区切られた文字列の次に一般的な区切り文字です。ほとんどのテキストにパイプが含まれている可能性は低く、ord('|') は 124 を返すので、要件に合っているようです。
擬似印刷可能で、通常の使用ではほとんど出てこない ascii 0x7f を使用します。
勝利へのパイプ!| |
テキストの性質にもある程度依存しますが、垂直バー 0x7C がテキスト内に表示されることはあまりありません。
これは、状況や言語によって、良い場合も悪い場合もありますが (通常は悪い場合が多い)、いつでもすべてを Base64 でエンコードできることに注意してください。次に、両側でさまざまなパターンをエスケープおよびエスケープ解除することを心配する必要はなく、Base64 文字セットで使用されていない文字に基づいて文字列を単純に分離および分割できます。
XMLドキュメントをXMLプロパティ/ノードに配置することに直面したとき、私はこのソリューションに頼らなければなりませんでした。プロパティには CDATA ブロックをまったく含めることはできません。CDATA としてエスケープされたノードは、構造を壊さずにその中にさらに CDATA ブロックを含めることはできません。
ただし、CSV はおそらくほとんどの状況でより良いアイデアです。
アンパサンドの後にコンマが続く自然なテキストを見たことはないと思いますが、最初にファイルをチェックして、区切り文字が含まれているかどうかを確認し、含まれている場合は別の方法を使用してください。使用する区切り文字が競合を引き起こさないことを常に知りたい場合は、目的の区切り文字についてファイルをチェックするループを実行し、存在する場合は、ファイルが一致しなくなるまで文字列を 2 倍にします。 . プログラムは正確な区切り文字の一致のみを検索するため、同様の文字列があっても問題ありません。