2012-12-04 78 views
0

這已被問到幾種不同的方式,但我正在與另一名開發人員討論「我的方式」與「你的方式」。語言是C#。解析C中分隔字符串的最有效的方法#

我想解析一個管道分隔字符串,其中每個塊的前2個字符是我的標記。

規則。不是我的規則,而是我已經給予並且必須遵守的規則。 我無法更改字符串的格式。 這個函數可能會被調用很多次,所以效率是關鍵。 我需要保持簡單。 我正在查找的輸入字符串和標籤可能會在運行時更改。

實施例的輸入字符串:AOVALUE1 | ABVALUE2 | ACVALUE3 | ADVALUE4 實施例標籤我可能需要值:我分裂串到每個函數被調用時基於定界符和循環通過該陣列的陣列AB

。然後,我查看了前2個字符,並將值減去前2個字符。

「其他人」的方式是採取字符串,並使用IndexOf和SubString的組合來查找我所尋找的字段的起點和終點。然後再次使用SubString來拉出值減去前2個字符。所以他會說IndexOf(「| AB」)查找字符串中的下一個管道。這將是開始和結束。然後SubString出來。

現在我應該認爲IndexOf和SubString會每次在char by char level處解析字符串,所以這比使用大塊和讀取字符串減去前2個字符的效率要低。還是有另一種方式,比我們兩個人提出的更好?

+0

如果輸入字符串不經常更改,然後您可以創建一個字典,您可以一次解析字符串,併爲每個標記/值對執行Dictionary.Add(tag,value)。你也可以做一些延遲加載,在那裏你解析字符串的一部分,直到你找到你想要的值(同時把你發現的所有東西加到字典中),然後在下一次搜索字典。並繼續解析,如果你沒有找到它。 –

+0

想過這個。輸入字符串和標籤幾乎可以每次都改變。我提出了使用集合的各種方法,但建議使用某種類型的解析。 – SpaceMonkey

回答

1

像這樣的東西可以工作正常

string myString = "AOVALUE1|ABVALUE2|ACVALUE3|ADVALUE4"; 
string selector = "AB"; 

var results = myString.Split('|').Where(x => x.StartsWith(selector)).Select(x => x.Replace(selector, "")); 

返回:比賽的名單,在這種情況下,只有一個「VALUE2」

如果你只是尋找的第一個或唯一匹配,這將工作。

string result = myString.Split('|').Where(x => x.StartsWith(selector)).Select(x => x.Replace(selector, "")).FirstOrDefault(); 
+0

這將返回以下內容。 System.Linq.Enumerable + WhereSelectArrayIterator'2 [System.String,System.String] – SpaceMonkey

+0

它返回匹配列表(IEnumerable)我不確定您是否期待多個結果 –

+0

已更新的答案僅返回一個結果/匹配 –

1

我已經做了在C#中解析的很多,我可能會採取的「其他人」提出的辦法,只是因爲它是在使用,並且有可能會快一點,以及資源打火機一點。

也就是說,只要數據不是太大,第一種方法沒有什麼問題,編程起來也會更容易。

0
  • 串不解析字符串。
  • IndexOf解析字符串。

我更傾向於將拆分方法,主要是代碼的編碼效率:

string[] inputArr = input.Split("|".ToCharArray()).Select(s => s.Substring(3)).ToArray(); 

是相當簡潔。 substring/indexof方法需要多少個LoC?

+0

每次調用函數時,我正在尋找的整個字符串和標記都將進入。輸入字符串也可能變大。根據我的字符串示例,我可能會有多達20個標籤,其值未知。 – SpaceMonkey

2

鑑於輸入字符串需要每次重新評估,其他人的方法將會更加高效。如果輸入字符串很長,也不需要分割字符串的額外內存。

如果我想編寫一個非常緊密循環,我更喜歡直接用數組/串運營商,而不是LINQ,以避免額外的開銷:

string inputString = "AOVALUE1|ABVALUE2|ACVALUE3|ADVALUE4"; 

static string FindString(string tag) 
{ 
    int startIndex; 
    if (inputString.StartsWith(tag)) 
    { 
     startIndex = tag.Length; 
    } 
    else 
    { 
     startIndex = inputString.IndexOf(string.Format("|{0}", tag)); 
     if (startIndex == -1) 
      return string.Empty; 

     startIndex += tag.Length + 1; 
    } 

    int endIndex = inputString.IndexOf('|', startIndex); 
    if (endIndex == -1) 
     endIndex = inputString.Length; 

    return inputString.Substring(startIndex, endIndex - startIndex); 
} 
+0

看來我不能有2個答案,但這也適用。有一個基於LINQ的單線程也可以工作。在上面發佈。我將介紹他們並看看他的想法。 – SpaceMonkey