2009-10-27 51 views
1

嗨,鑑於以純​​文本格式的數據集,如下列:如何解析一些維基標記

==Events== 
* [[312]] – [[Constantine the Great]] is said to have received his famous [[Battle of Milvian Bridge#Vision of Constantine|Vision of the Cross]]. 
* [[710]] – [[Saracen]] invasion of [[Sardinia]]. 
* [[939]] – [[Edmund I of England|Edmund I]] succeeds [[Athelstan of England|Athelstan]] as [[King of England]]. 
*[[1275]] – Traditional founding of the city of [[Amsterdam]]. 
*[[1524]] – [[Italian Wars]]: The French troops lay siege to [[Pavia]]. 
*[[1553]] – Condemned as a [[Heresy|heretic]], [[Michael Servetus]] is [[burned at the stake]] just outside [[Geneva]]. 
*[[1644]] – [[Second Battle of Newbury]] in the [[English Civil War]]. 
*[[1682]] – [[Philadelphia]], [[Pennsylvania]] is founded. 

我想結束了集合的NSDictionary或其他形式,這樣我可以有年份(左側的數字)映射到摘錄(右側的文本)。原來這就是「模板」是這樣的:

*[[YEAR]] – THE_TEXT 

雖然我想摘錄是純文本,也就是沒有維基標記所以沒有[[套。實際上,使用別名鏈接(例如[[Edmund I of England|Edmund I]])可能會很困難。

我不是那種經驗豐富的正則表達式,所以我有幾個問題。我應該首先嚐試「美化」數據嗎?例如,刪除始終爲==Events==的第一行,並刪除發生的[[]]

或者更好的解決方案:我應該在通行證中這樣做嗎?舉例來說,第一遍我可以將每行分隔成* [[710]][[Saracen]] invasion of [[Sardinia]]。並將它們存儲到不同的NSArrays

然後經過第一NSArray多年,只得到了[[]]內的文本(我說的文本,而不是數字,因爲它可以公元前530年),所以* [[710]]變得710

再來說摘錄NSArray,經歷以及如果[[some_article|alias]]發現,使它只能是[[alias]]不知何故,然後刪除所有[[]]套?

這可能嗎?我應該使用正則表達式嗎?你有什麼想法可以提出正則表達式可能有幫助嗎?

謝謝!對此,我真的非常感激。

編輯:對不起,我只是想解析上述數據。假設這是我遇到的唯一標記類型。我不一定期待解析wiki標記,除非已經有一個預先存在的庫來執行此操作。再次感謝!

回答

3

此代碼假定您使用的是RegexKitLite

NSString *data = @"* [[312]] – [[Constantine the Great]] is said to have received his famous [[Battle of Milvian Bridge#Vision of Constantine|Vision of the Cross]].\n\ 
    * [[710]] – [[Saracen]] invasion of [[Sardinia]].\n\ 
    * [[939]] – [[Edmund I of England|Edmund I]] succeeds [[Athelstan of England|Athelstan]] as [[King of England]].\n\ 
    *[[1275]] – Traditional founding of the city of [[Amsterdam]]."; 

    NSString *captureRegex = @"(?i)(?:\\* *\\[\\[)([0-9]*)(?:\\]\\] \\–)(.*)"; 

    NSRange captureRange; 
    NSRange stringRange; 
    stringRange.location = 0; 
    stringRange.length = data.length; 

    do 
    { 
     captureRange = [data rangeOfRegex:captureRegex inRange:stringRange]; 
     if (captureRange.location != NSNotFound) 
     { 
      NSString *year = [data stringByMatching:captureRegex options:RKLNoOptions inRange:stringRange capture:1 error:NULL]; 
      NSString *textStuff = [data stringByMatching:captureRegex options:RKLNoOptions inRange:stringRange capture:2 error:NULL]; 
      stringRange.location = captureRange.location + captureRange.length; 
      stringRange.length = data.length - stringRange.location; 
      NSLog(@"Year:%@, Stuff:%@", year, textStuff); 
     } 
    } 
    while (captureRange.location != NSNotFound); 

請注意,你真的需要上晚自習的正則表達式的構建這些很好,但這裏是一個我是說:

(?i) 

忽略大小寫,因爲我沒有匹配字母,所以我可以將它留下。

(?:\* *\[\[) 

:表示不抓住這個塊,我逃*與之相匹配的,然後有零個或多個空格(「*」),那麼我逃出兩個支架(支架以來也是特殊字符一個正則表達式)。

([0-9]*) 

抓住任何一個數字。

(?:\]\] \–) 

這裏是我們再次忽略東西的地方,基本上匹配「–」。注意正則表達式中的任何「\」,我必須在上面的Objective-C字符串中添加另一個,因爲「\」是字符串中的特殊字符......並且是表示匹配正則表達式轉義的單個「\」結束在Obj-C字符串中寫成「\\」。

(.*) 

只要抓住任何東西,默認情況下,正則表達式引擎將停在一條線這就是爲什麼它不只是匹配一切結束匹配。您必須添加代碼才能從文本中刪除[[LINK]]內容。

NSRange變量用於通過文件保持匹配而不重新匹配原始匹配。可以這麼說。

添加RegExkitLite類文件後,您還需要添加特殊的鏈接器標記,否則會得到大量鏈接錯誤(RegexKitLite站點有安裝說明)。

0

我對正則表達式不太擅長,但這聽起來像是他們的工作。我想象一個正則表達式會很容易地爲你排序。

看看RegexKitLite庫。

+0

謝謝,是的,有人把我介紹給那個圖書館。 (我沒有讓你失望)。 – 2009-10-27 22:40:49

0

如果你想能夠解析一般的Wikitext,你有很多工作要做。一個複雜的因素是模板。你想要付出多少努力來應對這些?

如果您認真對待此問題,您可能應該查找解析Wikitext的現有庫。簡單的看一輪發現this CPAN library,但我沒有使用它,所以我不能引用它作爲個人的建議。

或者,您可能想要採取更簡單的方法並確定您將要應對的Wikitext的哪些特定部分。例如,這可能是鏈接和標題,但不是列表。然後,您必須將注意力集中在每一項上,並將Wikitext轉換爲您想要的樣子。是的,正則表達式對這一點有很大的幫助,所以仔細閱讀它們,如果你有特定的問題,請回來問一下。

祝你好運!

+0

非常感謝我的迴應,但我不想解析整個維基百科標記,只是我發佈的那一點,它通常只包含那種類型的標記。假設這是唯一會出現的標記類型。對困惑感到抱歉! – 2009-10-27 23:00:26