2012-09-12 65 views
1

我遇到問題,我想知道是否有任何智能解決方法。使用字符串中存在的分隔符分割字符串

我需要通過插座來傳遞一個字符串到Web應用程序。這個字符串有三個部分,我使用'|'作爲分隔符,將接收應用程序分成三個獨立的部分。

問題在於'|'角色可以是任何3個單獨字符串中的字符,當發生這種情況時,整個分割動作會扭曲字符串。

因此,我的問題是這樣的: 有沒有辦法在一些文本中使用字符/字符串作爲分隔符,而這個字符/字符串本身可能在文本中?

+0

你有控制兩端嗎? – Rawling

+0

你能告訴你如何將字符串傳遞給套接字嗎?您是否使用StreamStream的NetworkStream? – opewix

+0

@JesseJames - 與OPs問題無關。 –

回答

2

一般模式是逃避分隔符。例如。當'|'是分隔符,你可以使用「||」每當你在字符串內部需要字符本身(如果你允許空字符串可能會很困難),或者你可以使用'\'作爲轉義字符,這樣'|'變成「\ |」和「\」本身就是「\\」

+0

哦,我明白了,是的,我認爲這可以做到這一點。但作爲一般原則,EXACT字符串似乎不能以某種方式用作分隔符,因此您必須「自定義」它自身或其他內容,這會導致新的定製字符串不符合文本內容,等等。 。 – Redg

0

也許是對的HTMLEncode有用的,第一HTMLDecode你的字符串,然後與你的分隔符一起附上他們。

+0

我做的HTMLEncode和HTMLDecode適當這些數據對問題的本質沒有任何影響,因爲最終在解碼後它具有你發送的第一個位置 – Redg

0

我認爲你要麼

1)發現,將永遠不會出現在字符串

2)使用固定長度的字符串和墊在字符或字符集在一起。

1

有沒有辦法在一些文本中使用char/string作爲分隔符,而 這個char/string本身可能在文本中?

答案很簡單:

這當然是當字符串/分隔符是正是一樣,沒有做修改文本。

當然也有可能的解決方法。一種可能的解決方案是您可能希望在分隔符之間具有最小/固定寬度,但這並不完美。

另一種可能的解決方案是選擇將永遠不會在你的文字一起出現一個分隔符(字符序列)。這要求您更改來源和消費者。

當我需要用分隔符我通常選擇,我肯定會在正常的文本不會發生99.9%的分隔符,分隔符可以取決於什麼樣的文字,我希望會有所不同。

下面是引自Wikipedia

因爲分隔符碰撞很常見的問題,不同的方法 避免它被髮明出來。有些作者可能會嘗試通過選擇不可能出現在數據流本身中的分隔符(或字符序列)來避免 問題。 這個特設的方法可能是合適的,但它必然取決於將出現在數據流中有什麼 正確的猜測,並提供針對惡意碰撞沒有 安全。其他更正式的約定 因此也適用。

只是對您的用例的一個附註,爲什麼不使用協議來發送數據?如protobuf

+0

有趣的是,看到投票計數器的答案在-2和+之間上下移動, 4非常快:) –

+0

似乎,主要原因是你很短暫和快速回答 –

+0

@Andreas,雖然不斷更新它;增加更多信息。 :) –

0

如果您有這個靈活性,也許可以調整分隔符?因此,而不是String1 | String2字符串可以讀取「String1」|「String2」。

如果管道是不需要的 - 在創建/輸入這個字符串的過程中進行一些簡單的驗證?

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(); 
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]); 

這不是最有效可行的解決方案,因爲它需要掃描的消息部分幾次,但它是非常易於實施。如果您找不到delimiter的值,並且null恰好是消息的一部分,則可能會遇到意外的結果。