如何解析一些Wiki标记 [英] How to Parse Some Wiki Markup

查看:134
本文介绍了如何解析一些Wiki标记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,给定一个以纯文本形式显示的数据集,如下所示:

Hey guys, given a data set in plain text such as the following:

==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或其他形式的结尾,这样我就可以将年份(左侧的数字)映射到摘录(右侧的文本).这就是模板"的样子:

I would like to end up with an NSDictionary or other form of collection so that I can have the year (The Number on the left) mapping to the excerpt (The text on the right). So this is what the 'template' is like:

*[[YEAR]] – THE_TEXT

尽管我希望摘录是纯文本,也就是说,没有Wiki标记,所以没有设置[[.实际上,使用[[Edmund I of England|Edmund I]]之类的别名链接可能很难证明这一点.

Though I would like the excerpt to be plain text, that is, no wiki markup so no [[ sets. Actually, this could prove difficult with alias links such as [[Edmund I of England|Edmund I]].

我对正则表达式不是很了解,所以我有几个问题.我应该首先尝试美化"数据吗?例如,要删除始终为==Events==的第一行,并删除[[]]出现的内容?

I am not all that experienced with regular expressions so I have a few questions. Should I first try to 'beautify' the data? For example, removing the first line which will always be ==Events==, and removing the [[ and ]] occurrences?

也许是一个更好的解决方案:我应该分阶段进行吗?因此,例如,第一遍,我可以将每行分成* [[710]][[Saracen]] invasion of [[Sardinia]].并将它们存储在不同的NSArrays中.

Or perhaps a better solution: Should I do this in passes? So for example, the first pass I can separate each line into * [[710]] and [[Saracen]] invasion of [[Sardinia]]. and store them into different NSArrays.

然后经历年份的头一个NSArray,仅在[[]]之内得到文本(我说的是文本,而不是数字,因为它可能是公元前530 ),因此* [[710]]变为710.

Then go through the first NSArray of years and only get the text within the [[]] (I say text and not number because it can be 530 BC), so * [[710]] becomes 710.

然后对于摘录的NSArray进行检查,如果找到了[[some_article|alias]],则以某种方式使其仅成为[[alias]],然后删除所有的[[]]集?

And then for the excerpt NSArray, go through and if an [[some_article|alias]] is found, make it only be [[alias]] somehow, and then remove all of the [[ and ]] sets?

这可能吗?我应该使用正则表达式吗?对于正则表达式,您能提出什么建议吗?

Is this possible? Should I use regular expressions? Are there any ideas you can come up with for regular expressions that might help?

谢谢!我真的很感激.

编辑:很抱歉造成混乱,但是我只想解析以上数据.假设那是我将遇到的唯一标记类型.我不一定总希望解析Wiki标记,除非已经有一个预先存在的库可以做到这一点.再次感谢!

EDIT: Sorry for the confusion, but I only want to parse the above data. Assume that that's the only type of markup that I will encounter. I'm not necessarily looking forward to parsing wiki markup in general, unless there is already a pre-existing library which does this. Thanks again!

推荐答案

此代码假定您使用的是 RegexKitLite :

This code assumes you are using 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才能很好地构建它们,但这就是我所说的:

Note that you really need to study up on RegEx's to build these well, but here's what the one I have is saying:

(?i)

忽略大小写,因为我不匹配字母,所以我可以忽略掉它.

Ignore case, I could have left that out since I'm not matching letters.

(?:\* *\[\[)

?:表示不捕获此块,我将*进行匹配以将其转义,然后有零个或多个空格("*"),然后我将两个方括号转义(因为方括号也是正则表达式中的特殊字符).

?: means don't capture this block, I escape * to match it, then there are zero or more spaces (" *") then I escape out two brackets (since brackets are also special characters in a regex).

([0-9]*)

抓住任何数字.

(?:\]\] \– )

这里是我们再次忽略内容的地方,基本上与–"匹配.注意正则表达式中的任何"\",我必须在上面的Objective-C字符串中添加另一个,因为"\"是字符串中的特殊字符...是的,这意味着匹配正则表达式转义的单个"\"结尾在Obj-C字符串中显示为"\\".

Here's where we ignore stuff again, basically matching " – ". Note any "\" in the regex, I have to add another one to in the Objective-C string above since "\" is a special character in a string... and yes that means matching a regex escaped single "\" ends up as "\\" in an Obj-C string.

(.*)

只需抓取其他任何东西,默认情况下,RegEX引擎都会在一行的末尾停止匹配,这就是为什么它不仅仅匹配其他所有内容的原因.您必须添加代码才能从文本中删除[[LINK]]内容.

Just grab anything else, by default the RegEX engine will stop matching at the end of a line which is why it doesn't just match everything else. You'll have to add code to strip out the [[LINK]] stuff from the text.

NSRange变量用于在整个文件中保持匹配,而无需重新匹配原始匹配.可以这么说.

The NSRange variables are used to keep matching through the file without re-matching original matches. So to speak.

添加RegExKitLite类文件后不要忘记,还需要添加特殊的链接器标志,否则会出现很多链接错误(RegexKitLite网站上有安装说明).

Don't forget after you add the RegExKitLite class files, you also need to add the special linker flag or you'll get lots of link errors (the RegexKitLite site has installation instructions).

这篇关于如何解析一些Wiki标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆