Как разобрать вики-разметку - PullRequest
1 голос
/ 28 октября 2009

Привет, ребята, учитывая набор данных в виде простого текста, например:

==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]], а затем удалите все наборы [[ и ]]?

Возможно ли это? Должен ли я использовать регулярные выражения? Есть ли какие-нибудь идеи, которые вы можете придумать для регулярных выражений, которые могут помочь?

Спасибо! Я действительно ценю это.

РЕДАКТИРОВАТЬ : Извините за путаницу, но я хочу только проанализировать вышеупомянутые данные. Предположим, что это единственный тип разметки, с которым я столкнусь. Я не обязательно с нетерпением ожидаю парсинга разметки вики в целом, если только не существует уже существующей библиотеки, которая делает это. Еще раз спасибо!

Ответы [ 3 ]

3 голосов
/ 30 октября 2009

Этот код предполагает, что вы используете 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)

Игнорировать регистр, я мог бы пропустить это, поскольку я не соответствую буквам.

(?:\* *\[\[)

?: означает, что не захватывать этот блок, я экранирую *, чтобы соответствовать ему, затем пробел или ноль ("*"), а затем я убираю две скобки (поскольку скобки также являются специальными символами в регулярном выражении)

([0-9]*)

Хватайте все, что является числом.

(?:\]\] \– )

Здесь мы снова игнорируем вещи, в основном совпадая с "& ndash;". Обратите внимание на любое "\" в регулярном выражении, я должен добавить еще один в строке Objective-C выше, так как "\" является специальным символом в строке ... и да, это означает, что совпадение с экранированным регулярным выражением одиночным "\" заканчивается как "\\" в строке Obj-C.

(.*)

Просто возьмите что-нибудь еще, по умолчанию движок RegEX прекратит сопоставление в конце строки, поэтому он не просто сопоставляет все остальное. Вам нужно будет добавить код, чтобы вырезать текст [[LINK]] из текста.

Переменные NSRange используются для продолжения сопоставления через файл без повторного сопоставления исходных совпадений. Так сказать.

Не забудьте после добавления файлов классов RegExKitLite, вам также необходимо добавить специальный флаг компоновщика, иначе вы получите множество ошибок ссылок (на сайте RegexKitLite есть инструкции по установке).

0 голосов
/ 28 октября 2009

Если вы хотите иметь возможность анализировать Викитекст в целом, у вас много работы. Только один усложняющий фактор - шаблоны. Сколько усилий вы хотите сделать, чтобы справиться с этим?

Если вы серьезно относитесь к этому, вам, вероятно, следует поискать существующую библиотеку, которая анализирует Wikitext. Краткий осмотр находит эту библиотеку CPAN , но я не использовал ее, поэтому не могу назвать ее личной рекомендацией.

В качестве альтернативы, вы можете выбрать более простой подход и решить, с какими частями Викитекста вы будете справляться. Это могут быть, например, ссылки и заголовки, но не списки. Затем вы должны сосредоточиться на каждом из них и превратить Викитекст в то, что вы хотите, чтобы он выглядел. Да, регулярные выражения очень помогут с этим битом, так что читайте их, и если у вас есть конкретные проблемы, вернитесь и спросите.

Удачи!

0 голосов
/ 28 октября 2009

Я не очень хорошо разбираюсь в регулярных выражениях, но для них это звучит как работа. Я полагаю, что регулярное выражение очень легко с этим справится.

Взгляните на библиотеку RegexKitLite.

...