Regix: Извлечение списка шаблонов из XML-документа MediaWiki - PullRequest
1 голос
/ 27 октября 2019

Я пытаюсь использовать дамп базы данных вики-сайта Vocaloid для извлечения списка URL каждой песни в список. Каждая из тысяч песен хранит свои URL в шаблоне {{Song box 2}}. Дамп базы данных находится в формате XML-документа MediaWiki.

{{Song box 2
  |color     = #AC9381; color:#445A56
  |image     = ハチ - 砂の惑星.png
  |title     = "'''砂の惑星'''"
* Romaji: Suna no Wakusei
* English: Sand Planet
* Official English: DUNE
  |date      = July 21, 2017
  |views     = {{v|nn|6,947,105}} and {{v|yt|46,753,728}}
  |singers   = [[Hatsune Miku]]
  |producers = [[Hachi]] (music, lyrics, arrangement)
* [[Minakata Laboratory]] (video)
  |links     = {{l|nn|sm31606995}} {{l|yt|AS4q9yaWJkI}}
}}

Чтобы преобразовать XML-документ MediaWiki в более работоспособный формат для извлечения URL-адресов, я использовал анализатор wtf_wikipedia для преобразования документа в JSON.

var fs = require('fs');
const wtf = require('wtf_wikipedia');

const wikiText = fs.readFileSync('vocaloid_pages_current.xml', 'utf-8');
var data = wtf(wikiText).json();
fs.writeFile('output.json', JSON.stringify(data, null, '\t'), 'utf8', function (err) {
    if (err) {
        console.log("An error occured while writing JSON Object to File.");
        return console.log(err);
    }
    console.log("JSON file has been saved.");
});

Однако возвращенный JSON удаляет ссылки идентификатора, используемого для определения того, какому веб-сайту соответствует идентификатор видео. В то время как можно было бы угадать сайт, основываясь на том, как отформатирован идентификатор видео, синтаксический анализ всего документа XML таким способом уже очень медленный и не является хорошим решением моей проблемы.

{
"color": "#AC9381; color:#445A56",
"image": "ハチ - 砂の惑星.png",
"title": ""砂の惑星"\n* Romaji: Suna no Wakusei\n* English: Sand Planet\n* Official English: DUNE",
"date": "July 21, 2017",
"views": "and",
"singers": "Hatsune Miku",
"producers": "Hachi (music, lyrics, arrangement)\n* Minakata Laboratory (video)",
"links": "sm31606995 AS4q9yaWJkI",
"template": "song box 2"
}   

Мой следующийИдея собрать все URL-адреса песни состоит в том, чтобы создать список всего текста внутри шаблонов {{Song box 2}} и проанализировать URL-адреса оттуда. Чтобы создать список текста внутри шаблонов {{Song box 2}}, я попытался использовать регулярные выражения. Однако регулярное выражение , которое я создал вместо выделения всего текста внутри шаблона {{Song box 2}}, остановится при первом появлении }} внутри шаблона.

Как можноЯ использую регулярные выражения для создания списка текста внутри {{Song box 2}} шаблонов?

Edit 1

Ввод шаблона регулярного выражения, предоставленного @jhnc, в скрипт нижеуспешно соответствует 4 194 из 7 196, что я и ожидал. Я полагаю, что это потому, что некоторые из {{Song box 2}} имеют символы до {{Song box 2}} на одной строке. См. Обновленный пример регулярных выражений .

var fs = require('fs');
const wikiText = fs.readFileSync('vocaloid_pages_current.xml', 'utf-8');
const regex = /^\{\{Song box 2(\s*?.*?)*?^\}\}/gm;
const matches = [];
let match;
while ((match = regex.exec(wikiText)) !== null) {
  if (match.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    matches.push(match[0]);
}
console.log(matches.length); // 4194

Как я могу также сопоставить эти вхождения?

...