Справка по регулярному выражению для разметки шаблона MediaWiki

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

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

Я разбираю разметку MediaWiki и пытаюсь получить имена шаблонов MediaWiki. Они обозначаются чем-то вроде:

{{Название шаблона|другое

or

{{Имя шаблона}}

Если # сразу следует за фигурными скобками:

{{#Другое

Я хотел бы игнорировать это.

So...

Я хотел бы сопоставить 2 фигурные скобки {{, за которыми не следует #, до следующего вхождения любого | (вертикальная черта) или }} (2 закрывающих завитка)

So:

{{Я лягушка|кое-что еще соответствует

{{#Я лягушка|кое-что ещё не получается

мусор здесь{{Monkey}}бла-бла соответствие

мусор здесь{{#Monkey}}бла-бла сбой

и т.д...

Следующее регулярное выражение охватывает это (я думаю):

\{{2}(?!\#)(.*?)(?:\||\}\})

но также соответствует:

кое-что здесь {{{Giraffe|oijq

Как я могу заставить его потерпеть неудачу, если есть не ровно 2 открывающих фигурных скобки?

РЕДАКТИРОВАТЬ: регулярное выражение .net, кстати


person spender    schedule 06.08.2009    source источник
comment
то, что вы делаете, находится на границе зоны комфорта регулярных выражений. Вы можете это сделать, но в конечном итоге вы приложите к этому столько усилий, что, вероятно, захотите создать легкий синтаксический анализатор. Таким образом, когда вы устанавливаете новые синтаксисы и вкладываете их, вы не ходите по кругу.   -  person DevelopingChris    schedule 06.08.2009
comment
что должно {{{blah}}} отображаться как или как результат?   -  person DevelopingChris    schedule 06.08.2009
comment
Я знаю. Regex действительно отстой для этого, но уровень информации, который мне нужен из документа, очень мал, и мне нужно быстро их обработать, поэтому я действительно не могу позволить себе анализ.   -  person spender    schedule 06.08.2009


Ответы (3)


Возможно, вы захотите использовать отрицательное утверждение просмотра назад/вперед с нулевой шириной.

Lookbehind имеет тот же эффект, но работает в обратном направлении. Он сообщает обработчику регулярных выражений временно отступить назад в строке, чтобы проверить, можно ли там сопоставить текст внутри ретроспективного выражения. (?<!a)b соответствует "b", которому не предшествует "a", используя отрицательный поиск назад. Он не будет соответствовать «cab», но будет соответствовать b (и только b) в «bed» или «debt». (?<=a)b (положительный взгляд назад) соответствует b (и только b) в кабине, но не соответствует кровати или долгу.

So:

(?<!\{)\{{2}?(?!\#)(.*?)(?:\||\}\})

Другая проблема, которую я только что заметил, (.*?) будет соответствовать третьему фигурному... Вместо этого попробуйте добавить третий фигурный к отрицательному просмотру вперед, который вы уже используете для #

(?<!\{)\{{2}(?!\{*\#|\{+)(.*?)(?:\||\}\})
person gnarf    schedule 06.08.2009
comment
То же, что и мой комментарий к Даву. Кажется, это не так. - person spender; 06.08.2009
comment
обновленный ответ - не уверен, нужно ли вам избегать # или { в наборе, я не думаю, что вам нужно. - person gnarf; 06.08.2009
comment
В ПОРЯДКЕ. Даю вам ответ, поскольку вы были правы в отношении (.*?) соответствия третьей скобке, которая привела меня к ответу. Закончилось следующим: (?‹!\{)\{{2}(?!\{\#|\{+)(.?)(?:\||\}\ }) - person spender; 06.08.2009
comment
Круто - Редактирование ответа, чтобы включить его в качестве последнего примера - person gnarf; 06.08.2009

(?<!\{)\{{2}(?!\#)(.*?)(?:\||\}\})

Отрицательный просмотр назад нулевой ширины

(?<!\{)

соответствует только позиции, которая не находится непосредственно после фигурной скобки.

person Amber    schedule 06.08.2009

Возможно, хакерский wau в основном сделал бы ИЛИ НЕ с повторением одного и того же шаблона регулярного выражения, за исключением того, что он соответствовал бы 3 или более фигурным скобкам. Хотя, наверное, это не самое элегантное решение. Удачи.

person AaronLS    schedule 06.08.2009