2010-11-25 40 views
12

我有一個非常大的字符串(HTML),並在此HTML有特別的標記,其中所有的人都開始用「#」,並以「#」檢測字符串中的特定標記。 C#

簡單如

<html> 
<body> 
     <p>Hi #Name#, You should come and see this #PLACE# - From #SenderName#</p> 
</body> 
</html> 

我需要結束將檢測這些令牌並將其放入列表中的代碼。 0 - #名# 1 - ##地點2 - #發送者姓名#

我知道,我也許可以使用正則表達式,反正你有一些想法,這樣做呢?

回答

8

是你可以使用正則表達式。

string test = "Hi #Name#, You should come and see this #PLACE# - From #SenderName#"; 
Regex reg = new Regex(@"#\w+#"); 
foreach (Match match in reg.Matches(test)) 
{ 
    Console.WriteLine(match.Value); 
} 

正如您可能已經猜到\ w表示任何字母數字字符。 +表示它可能出現1次或更多次。你可以在這裏找到更多的信息msdn doc(對於.Net 4.你也會發現其他的版本)。

2

用途:

MatchCollection matches = Regex.Matches(mytext, @"#(\w+)#"); 

foreach(Match m in matches) 
{ 
    Console.WriteLine(m.Groups[1].Value); 
} 
+0

如果將正則表達式更改爲@「#(。*)#」 – T33C 2010-11-25 13:51:40

3
foreach (Match m in Regex.Matches(input, @"#\w+#")) 
    Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index); 
+0

該如何解析#您好#姓名#其中#正確放置#更多文本。只要它是一個單詞,它是否不會將「哈希」之外的單詞解析爲「外部」?還是我在這裏弄錯了? – 2010-11-25 13:36:36

+0

剛剛驗證 - 在你的例子中它給出了「#姓名#」和「#地點#」。當考慮多個匹配時,它們中的每一個都在前一個匹配結束後開始 - 也就是說,在匹配「#Name#」之後,它開始尋找第二個哈希符號後的下一個匹配項。 – VladV 2010-11-25 13:50:49

+0

+1:這很完美。我明白了爲什麼現在,因爲#實際上被第一場比賽「使用」了,因此也不能被第二場比賽使用。感謝您的啓發。 – 2010-11-25 14:28:53

10

你可以試試:

// using System.Text.RegularExpressions; 
// pattern = any number of arbitrary characters between #. 
var pattern = @"#(.*?)#"; 
var matches = Regex.Matches(htmlString, pattern); 

foreach (Match m in matches) { 
    Console.WriteLine(m.Groups[1]); 
} 

搶答this SO問題的啓發。

+2

+1是 - 考慮使用非貪婪。*匹配;雖然應該是。+? – 2010-11-25 13:37:32

+2

這會不會解析像這樣的文本:`你好#姓名#其中#地點#更多文本`,或者我誤解了有關RegEx如何工作的內容。這對OP來說可能不是一個有效的問題,所以這只是爲了我自己的好奇:) – 2010-11-25 13:46:13

4

沒有Regex一個變種,如果你喜歡:

var splitstring = myHtmlString.Split('#'); 
var tokens = new List<string>(); 
for(int i = 1; i < splitstring.Length; i+=2){ 
    tokens.Add(splitstring[i]); 
} 
0

使用Regex.Matches法的東西格式,如:

#[^#]+#的模式。

這可能是最天真的方式。

這可能再需要進行調整,如果你想避免包括在輸出匹配的「#」字符,可能與環視:

(?<=#)[^#]+(?=#)

(這樣做的一個匹配值是'你好」不是‘##你好’ - 所以你不必做任何更多的微調)

0

這使您可以標記列表的要求:

var tokens = new List<string>(); 
var matches = new Regex("(#.*?#)").Matches(html); 

foreach (Match m in matches) 
    tokens.Add(m.Groups[1].Value); 

編輯:如果你不要想包括英鎊字符,只需將它們移動到正則表達式字符串中的括號外(請參閱Pablo的答案)。

2

天真的解決方案:

var result = Regex 
    .Matches(html, @"\#([^\#.]*)\#") 
    .OfType<Match>() 
    .Select(x => x.Groups[1].Value) 
    .ToList(); 
2

試試這個

var result = html.Split('#') 
        .Select((s, i) => new {s, i}) 
        .Where(p => p.i%2 == 1) 
        .Select(t => t.s); 

說明:

一號線 - 我們分裂的字符 '#'

2號線的文本 - 我們選擇新的匿名類型,其中包括數組中的字符串位置以及字符串本身

line3 - 我們將匿名對象的列表篩選爲那些具有奇數索引值的列表 - 有效地選擇「其他」字符串 - 這適合於查找包含在哈希字符中的那些字符串,而不是那些位於

之外的字符串

4號線=我們剝去索引,並從匿名類型只返回字符串

1

Linq的解決方案:

 string s = @"<p>Hi #Name#, 
      You should come and see this #PLACE# - From #SenderName#</p>"; 

     var result = s.Split('#').Where((x, y) => y % 2 != 0).Select(x => x);