2011-11-15 80 views
2

我正在處理一個C#類來解析BBCodes從數據庫中爲PHPBB帖子拉出的文本。 在PHPBB有一個自定義的BBCode添加看起來像這樣:用C#解析多行BBCode正則表達式

[deck={TEXT1}]{TEXT2}[/deck] 

其中,坐在數據庫,看起來是這樣的:

[deck=FirstText:13giljne]Large Multiline Text[/deck:13giljne] 

我試圖替換使用正則表達式在C#中。 我的C#是這樣的:

string text = "[deck=FirstText:13giljne]Large Multiline Text[/deck:13giljne]"; 
string replace = "my replacement string"; 
string pattern = @"\[deck=((.|\n)*?)(?:\s*)\]((.|\n)*?)\[/deck(?:\s*)\]"; 
RegexOptions options = RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline; 
Regex regex = new Regex(pattern, options); 
string result = regex.Replace(text, replace); 

我敢肯定,這一切僅僅歸結到我的正則表達式是錯誤的。這對我來說並不令人意外,因爲Regex並不完全是我的強項。

在此先感謝。任何幫助是極大的讚賞。

編輯:由於有些人發現它不清楚,我會添加更大的例子。

源文:

[deck=Bant:13giljne]Item #1 
Item #2 
Item #3 
Item #4[/deck:13giljne] 

期望的結果:

<span>Bant</span> 
<div>Item #1 
Item #2 
Item #3 
Item #4</div> 

希望這給出了什麼,我試圖做一個更清晰的畫面。

+0

如果你能否詳細說明多一點......「我試圖取代,在C#中使用正則表達式」,試圖用什麼來代替呢? – m0skit0

+0

@ m0skit0我試圖讓正則表達式匹配被稱爲「text」的變量中的字符串,並將其替換爲名爲「replace」的變量中的字符串。 – Wayne

+0

但是,不是全部的字符串?爲什麼不使用*替換*而不是*文本*?我不明白你的問題... – m0skit0

回答

2

我認爲你的正則表達式顯示你需要匹配「First Text」和「Large Multiline Text」。

\[deck=([^\:]+?):(?:[^\]]+)\]([^\[]+?)\[/deck:(?:[^\]]+)\] 

這應該有幫助,它非常接近你的。

+0

這是完美的工作,謝謝! – Wayne

+1

我認爲你有一個bug。在試圖匹配'Large Multiline Text'的部分用'([^ \ [] +?)'替換'([^ \]] +?)''。您正在查找下一個左括號的所有內容,而不是下一個右括號。 –

+0

@Jim很好。 – Wayne

-1

如果你想替換"[deck=FirstText:13giljne]Large Multiline Text[/deck:13giljne]",不要使用正則表達式。使用替換。

string result= text.Replace("[deck=FirstText:13giljne]Large Multiline Text[/deck:13giljne]", replace); 

正則表達式通常用於字符串不完全已知但其結構已知的地方。

+0

這沒有幫助。 「FirstText」不是靜態值,「:13giljne」不是靜態值,「Large Multiline Text」不是靜態值。這些都是我無法控制的價值變量。這只是我需要匹配的數據庫中可能出現的一些事情的一個例子。 – Wayne

+2

@ m0skit0,恩,我認爲你不太清楚OP所要求的精神。 –

+0

我覺得韋恩做得不錯,特別是在第一個問題上。 – jwiscarson

1

如果您不熟悉正則表達式,您可以嘗試每次匹配一點,以確保字符串匹配。例如,給定的字符串:

string text = "[deck=FirstText:13giljne]Large Multiline Text[/deck:13giljne]"; 

編寫的第一部分相匹配的表達式:

string firstPart = "\[deck=[^\]]+\]"; 

[^\]]+說,「相匹配的一切,是不是]字符」。

驗證它匹配:

Match m = Regex.Match(text, firstPart); 

在第二部分然後粘性:

string firstAndSecond = firstPart + "[^\[]*"; 

並測試。

一旦這樣的工作,你可以添加最後一部分:

string search = firstAndSecond + "\[/deck[^\]]\]"; 

最後的正則表達式是(\[deck=[^\]]+\])([^\[]+)(\[/deck[^\]]+\]

我將各個部件分組以便更容易看到它們。你可以刪除這些組,如果你想或者讓它們不被捕獲。

編輯:

我從你想捕捉的FirstText你的編輯看到了,三組:

string search = "(\[deck=([^:]+):[^\]]+\])([^\[]+)(\[/deck[^\]]+\]"; 

替換字符串的話,會是這樣的:

string replace = "<span>$2</span>\n<div>$3</div>"; 
+0

我需要單獨與'[deck = FirstText:13giljne]'匹配第一部分,因爲我需要使用'[deck ='和':13giljne]之間的內容'。 – Wayne

+0

@Wayne:看我的編輯。 –

+0

您的最終正則表達式仍然與字符串不匹配。不過謝謝您的幫助。 – Wayne

0

在GitHub或Nuget上檢查STML Parser。它不使用RegEx,但效率更高,速度更快。

enter image description here