Рекурсивный шаблон PCRE с условием 1-го уровня {{1-уровень-тест: что-нибудь {{ne{{s}}ted}} }}
Я хочу сопоставить вложенные функции Wiki или функции синтаксического анализатора Wiki, которые начинаются с имени функции, а затем двоеточия, но как только я пытаюсь заставить рекурсивное регулярное выражение pcre работать с тестом 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)