1

問題があり、スマートな回避策があるかどうか疑問に思っています。

文字列をソケットからWebアプリケーションに渡す必要があります。この文字列は3つの部分で構成されており、「|」を使用します。受信アプリケーションで3つの別々の部分に分割するための区切り文字として。

問題は、「|」文字は、3つの別々の文字列のいずれかの文字にすることができ、これが発生すると、分割アクション全体が文字列を歪めます。

したがって、私の質問は次のとおりです。この文字/文字列自体がテキストに含まれている可能性があるときに、一部のテキストで文字/文字列を区切り文字として使用する方法はありますか?

4

7 に答える 7

2

一般的なパターンは、区切り文字をエスケープすることです。たとえば、「|」の場合 は区切り文字です。「||」を使用できます 文字列内に文字自体が必要な場合(空の文字列を許可すると難しい場合があります)、またはエスケープ文字として「\」のようなものを使用して「|」「\|」になります そして「\」自体は「\\」になります

于 2012-09-12T08:42:25.257 に答える
1

この文字/文字列自体がテキストに含まれている可能性があるときに、一部のテキストで文字/文字列を区切り文字として使用する方法はありますか?

簡単な答え:いいえ。

もちろん、これは、テキストに変更を加えずに、文字列/区切り文字がまったく同じである場合です。

もちろん、考えられる回避策があります。考えられる解決策の1つは、区切り文字の間に最小/固定幅を設定することですが、これは完全ではありません。

別の可能な解決策は、テキスト内で一緒に出現することのない区切り文字(文字のシーケンス)を選択することです。これには、ソースとコンシューマーを変更する必要があります。

区切り文字を使用する必要がある場合、通常、99.9%の確率で通常のテキストでは発生しないと確信している区切り文字を選択します。区切り文字は、予想するテキストの種類によって異なる場合があります。

これがウィキペディアからの引用です:

区切り文字の衝突は非常に一般的な問題であるため、それを回避するためのさまざまな方法が発明されています。一部の作成者は、データストリーム自体に表示されない可能性のある区切り文字(または文字のシーケンス)を選択することにより、問題を回避しようとする場合があります。このアドホックなアプローチは適切かもしれませんが、それは必然的にデータストリームに何が表示されるかを正しく推測することに依存し、悪意のある衝突に対するセキュリティを提供しません。したがって、他のより正式な規則も適用されます。

ユースケースの補足として、送信されるデータにプロトコルを使用してみませんか?protobufなど

于 2012-09-12T08:41:43.707 に答える
1

ここでの問題は、次の文字列が与えられた場合です。

string toParse = "What|do you|want|to|say|?";

これは、いくつかの方法で解析できます。

「何
をし
たい|言いたい|?」

また

「何|言い
たい
|言いたい|?」

等々...

文字列を解析するためのルールを定義することはできますが、コーディングは難しく、最終的なユーザーには直感に反しているように見えます。

文字列には、記号「|」を示すエスケープ文字が含まれている必要があります。セパレータではなく、必要です。これは、たとえば「\|」のようになります。

正規表現を使用した完全な例を次に示します。

using System.Text.RegularExpressions;

//... Put this in the main method of a Console Application for instance.
// The '@' character before the strings are to specify "raw" strings, where escape characters '\' are not escaped
Regex reg = new Regex(@"^((?<string1>([^\|]|\\\|)+)\|)((?<string2>([^\|]|\\\|)+)\|)(?<string3>([^\|]|\\\|)+)$");
string toTest = @"user\|dureuill|deserves|an\|upvote";
MatchCollection matches = reg.Matches(toTest);
if (matches.Count != 1)
{
    throw new FormatException("Bad formatted pattern.");
}

Match match = matches[0];
string string1 = match.Groups["string1"].Value.Replace(@"\|", "|");
string string2 = match.Groups["string2"].Value.Replace(@"\|", "|");
string string3 = match.Groups["string3"].Value.Replace(@"\|", "|");
Console.WriteLine(string1);
Console.WriteLine(string2);
Console.WriteLine(string3);
Console.ReadKey();
于 2012-09-12T09:39:46.847 に答える
0

最初に文字列をHTMLEncodeおよびHTMLDecodeしてから、区切り文字と一緒に添付すると便利な場合があります。

于 2012-09-12T08:40:43.060 に答える
0

私はあなたのどちらかだと思います

1)文字列に表示されない文字または文字のセットを一緒に検索します

また

2)固定長のストリングとパッドを使用します。

于 2012-09-12T08:40:53.983 に答える
0

あなたがこれを行う柔軟性を持っているなら、たぶん、デリメータを適応させますか?したがって、String1 | String2の代わりに、文字列は "String1"|"String2"と読み取ることができます。

パイプが不要な場合-この文字列の作成/入力中に簡単な検証を行いますか?

于 2012-09-12T08:42:13.860 に答える
0

区切り文字として使用する代わりに|、メッセージ部分に存在しない区切り文字を見つけて、送信されたメッセージの先頭に渡すことができます。区切り文字として整数を使用する例を次に示します。

String[] parts = {"this is a message", "it's got three parts", "this one's the last"};
String delimiter = null;

for (int i = 0; i < 100; i++) {
    String s = Integer.toString(i);
    if (parts[0].contains(s) || parts[1].contains(s) || parts[2].contains(s))
        continue;
    delimiter = s;
    break;
}

String message = delimiter + "#" + parts[0] + delimiter + parts[1] + delimiter + parts[2];

今、メッセージは0#this is a message0it's got three parts0this one's the lastです。

受信側では、区切り文字を見つけることから始めて、その上でメッセージ文字列を分割します。

String[] tmp = message.split("#", 2);
String[] parts = tmp[1].split(tmp[0]);

メッセージ部分を数回スキャンする必要があるため、これは最も効率的な解決策ではありませんが、実装は非常に簡単です。の値が見つからず、メッセージの一部である場合、予期しない結果が発生する可能性がありますdelimiternull

于 2012-09-12T10:23:40.810 に答える