代码之家  ›  专栏  ›  技术社区  ›  Jorge Israel Peña

如何解析某些wiki标记

  •  1
  • Jorge Israel Peña  · 技术社区  · 15 年前

    嘿,伙计们,给定一个纯文本的数据集,如下所示:

    ==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
    

    尽管我希望摘录是纯文本的,也就是说,没有wiki标记,所以没有 [[ 集合。事实上,这对于别名链接来说可能很困难,例如 [[Edmund I of England|Edmund I]] .

    我对正则表达式的经验不多,所以我有几个问题。我应该首先“美化”数据吗?例如,删除第一行 ==Events== ,并移除 [[ ]] 发生?

    或者一个更好的解决方案:我应该在通行证中这样做吗?例如,我可以把每一行分成 * [[710]] [[Saracen]] invasion of [[Sardinia]] . 把它们储存在不同的地方 NSArrays .

    然后通过第一个 NSArray 而且只在 [[]] ( 我说的是文字而不是数字,因为它可以 公元前530年 如此 *[〔710〕 变成 710 .

    然后是摘录 不可变数组 ,通过,如果 [[some_article|alias]] 找到了,就让它 [[alias]] 然后把所有的 [[ ] ] 集合?

    这有可能吗?我应该使用正则表达式吗?对于正则表达式,你有什么想法可以帮助你吗?

    谢谢!我真的很感激。

    编辑 :很抱歉弄混了,但我只想解析上面的数据。假设这是我将遇到的唯一一种标记类型。一般来说,我并不希望解析wiki标记,除非已经有一个现成的库可以这样做。再次感谢!

    3 回复  |  直到 15 年前
        1
  •  3
  •   Kendall Helmstetter Gelner    15 年前

    此代码假定您正在使用 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 );
    

    请注意,您确实需要学习regex才能构建好这些,但我要说的是:

    (?i)
    

    忽略大小写,因为我不匹配字母,所以我本可以忽略不计。

    (?:\* *\[\[)
    

    是吗?:表示不要捕获此块,我转义*以匹配它,然后有零个或多个空格(“*”),然后我转义两个方括号(因为方括号也是regex中的特殊字符)。

    ([0-9]*)
    

    带上任何数字。

    (?:\]\] \– )
    

    这里我们又忽略了一些东西,基本上是匹配的“–”。请注意,在regex中,我必须在上面的objective-c字符串中添加另一个\“,因为\”是字符串中的特殊字符…是的,这意味着在obj-c字符串中匹配一个regex转义的单个\“以\”结尾。

    (.*)
    

    只要抓取其他东西,默认情况下,regex引擎将在行尾停止匹配,这就是为什么它不只是匹配其他东西的原因。你必须添加代码才能从文本中去掉[[链接]]的内容。

    NSRANGE变量用于在不重新匹配原始匹配项的情况下通过文件保持匹配。可以这么说。

    别忘了添加regexkitlite类文件后,还需要添加特殊的链接器标志,否则会出现很多链接错误(regexkitlite站点有安装说明)。

        2
  •  0
  •   Jasarien    15 年前

    我不擅长正则表达式,但这听起来像是他们的工作。我想一个正则表达式可以很容易地为您解决这个问题。

    看看regexkitlite库。

        3
  •  0
  •   Tim Palak Chaudhary    15 年前

    如果您希望能够大体上解析维基文本,那么您有很多工作要做。唯一复杂的因素是模板。你想做多少努力来应付这些?

    如果你是认真的,你可能应该找一个现有的库来解析维基文本。一个简单的环视发现 this CPAN library 但是我没有用过,所以我不能把它作为个人推荐。

    或者,您可能希望采用一种更简单的方法,并决定要处理的维基文本的特定部分。例如,这可能是链接和标题,但不是列表。然后你必须把注意力集中在每一个上面,把维基文本变成你想要的样子。是的,正则表达式在这方面会有很大帮助,所以请仔细阅读它们,如果您有特定的问题,请回来询问。

    祝你好运!

    推荐文章