Рекурсивный шаблон PCRE с условием 1-го уровня {{1-уровень-тест: что-нибудь {{ne {{s}} ted}}}}

Я хочу сопоставить вложенные функции Wiki или функции синтаксического анализатора Wiki, которые начинаются с имени функции, а затем двоеточия, но как только я пытаюсь получить рекурсивное регулярное выражение работая с тестом 1-го уровня, я не могу построить шаблон регулярных выражений. Я хочу соответствовать тесту, с которого начинается {{aFunctionName: с последующим двоеточием в регулярном выражении {{[\w\d]+: тестовый текст может выглядеть так

1 {{DEFAULTSORT: shall be matched {{PAGENAME}} }}
2 {{DEFAULTSORT: shall be matched }}
3 {{DEFAULTSORT: shall be matched {{PAGENAMEE: some text}} }}
4 Lorem ipsum {{VARIABLE shall not be matched}}
5 {{Some template|param={{VARIABLE}} shall not be matched }}

Я могу

  • получить любой вложенные фигурные скобки с использованием {{(?:(?:(?!{{|}}).)++|(?R))*}}
    который получает строки 1, 2, 3, частично 4 и 5
  • чтобы получить любую вложенную функцию вики, используя ({{(?:[\w\d]+:)(?:(?:(?!{{|}}).)++|(?1))*}})
    который получает только строку 3, но я также хочу сопоставить строки 1 и 2.

Но я понятия не имею, как создать шаблон регулярного выражения, который проверяет что-то вроде (написано как псевдокод):

{{match1st-level-Function: then anything {{nested}} or not nested }}
{{do not match simple {{nested}} things}}

Любая помощь от эксперта pcre regex? Спасибо!

1

Решение

Используйте что-то вроде этого:

{{\w+:([^{}]*+(?:{{(?1)}}[^{}]*)*+)}}

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

Другие возможные синтаксисы:

{{\w+:([^{}]*+(?:{{(?-1)}}[^{}]*)*+)}}
#                    ^------ relative reference: the last group on the left

{{\w+:([^{}]*+(?:{{\g<1>}}[^{}]*)*+)}}
#                  ^----- oniguruma syntax

{{\w+:([^{}]*+(?:{{\g<-1>}}[^{}]*)*+)}}
#                  ^----- relative with oniguruma syntax

{{\w+:(?<name>[^{}]*+(?:{{\g<name>}}[^{}]*)*+)}}
#                         ^---- named capture (oniguruma)

{{\w+:(?<name>[^{}]*+(?:{{(?&name)}}[^{}]*)*+)}}
#                         ^---- named capture (perl syntax)

Все эти синтаксисы могут быть использованы с pcre.

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

{{(?(R)|\w+:)[^{}]*+(?:(?R)[^{}]*)*+}}

Условный (?(R)|\w+:) и следует этой схеме: (?(condition) True | False)

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]