Я хочу сопоставить вложенные функции 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))*}}
({{(?:[\w\d]+:)(?:(?:(?!{{|}}).)++|(?1))*}})
Но я понятия не имею, как создать шаблон регулярного выражения, который проверяет что-то вроде (написано как псевдокод):
{{match1st-level-Function: then anything {{nested}} or not nested }}
{{do not match simple {{nested}} things}}
Любая помощь от эксперта pcre regex? Спасибо!
Используйте что-то вроде этого:
{{\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)
Других решений пока нет …