2012-02-15 78 views
0

我有一個字符串,可以包含任何內容,但99%的時間是幾個英語句子。.Net查找字符串中的所有字偏移量

我需要採取該字符串,並獲得代表每個詞的開始(或換句話說,在每個空白的結尾處)的索引列表。如果需要空白空間的定義,則至少需要Space,CR,LF和Period。

這樣做最簡單的方法是什麼?我認爲有一個比For循環更好的方法 - 我正在考慮使用lambda表達式,但我看不到一種方法來做到這一點不會遞歸 - 這似乎是乞求堆棧溢出...

示例數據:

Peter Piper picked a peck 
of pickled peppers 

希望的輸出是下面的數字。旁邊的評論說明:

6, 'Peter ' 
12, 'Peter Piper ' 
19, 'Peter Piper picked ' 
21, 'Peter Piper picked a ' 
26, 'Peter Piper picked a peck[CR]' 
29, 'Peter Piper picked a peck[CR]of ' 
37 'Peter Piper picked a peck[CR]of pickled ' 
+0

我用一個簡單的for循環去。你可以使用linq,但在這種情況下會更慢更醜。 – CodesInChaos 2012-02-15 22:56:23

+1

示例數據和所需輸出將會有所幫助。 – Alan 2012-02-15 22:56:59

+0

@Alan好點 - 編輯。 – Basic 2012-02-15 23:02:30

回答

2

這裏有一種方法,包含一個正則表達式一個lambda。它可能不是最有效的技術,但它是一個不錯的,聲明的一行:

var indices = Regex.Matches(inputString, @"[^\s\.]+") 
        .Cast<Match>() 
        .Select(match => match.Index) 
        .ToArray(); 
+0

非常優雅 - 我不得不與你分享。 – Basic 2012-02-16 00:03:25

1

對於這種情況,最好是主觀。在「哇,我可以使用一行代碼」方面可能更好,但由於您需要知道值的索引,因此簡單的for循環會很快寫入,並且更容易維護。

鑑於它是O(n)性能,應該足夠適合您的情況,我會說,只需使用for循環並繼續下一個問題即可。

+0

公平點 - 我明顯有太多的時間在我的手:) – Basic 2012-02-15 23:11:20

1

下面的函數,你需要什麼不for循環。不知道它實際上更短,雖然;)

static List<int> FindWordStarts(string sentence, Func<char, bool> is_separator) { 

    var indexes = new List<int>(); 
    bool separator = true; 

    sentence.Aggregate(
     0, 
     (index, c) => { 
      if (is_separator(c)) 
       separator = true; 
      else if (separator) { 
       indexes.Add(index); 
       separator = false; 
      } 
      return ++index; 
     } 
    ); 

    return indexes; 

} 

使用方法如下:

string sentence = "Peter Piper picked a peck\rof pickled peppers"; 
var indexes = FindWordStarts(sentence, c => Char.IsWhiteSpace(c) || Char.IsPunctuation(c)); 
foreach (int index in indexes) 
    Console.WriteLine(index); 

,其結果是:

0 
6 
12 
19 
21 
26 
29 
37 
+0

+1 - 比整個地方的狀態變量for循環更清晰,更具可讀性 – Basic 2012-02-16 00:04:51