Offshore
Новичок
PCRE: обход вложенных скобок с учётом их парности (рекурсивные подмаски)
В документации по пхп есть момент, описывающий получение содержимого скобок верхнего уровня с учётом парных скобок внутри.
Исходя из этого материала, получение выражения описывается так (с модификатором PCRE_EXTENDED), пока просто обратите внимание на выделение:
"\( ( (?: (?>[^()]+) | (?R) )*) \)", а если не оптимизировать, то так: "\( ( (?: [^()]+ | (?R) )*) \)".
Таким образом из строки "head (blabla(bla)blabla(bbllaa)) asdasd (bla(BLA)foo) tail" при использовании preg_match_all мы получим:
Array
(
_[0] => Array
__(
___[0] => (blabla(bla)blabla(bbllaa))
___[1] => (bla(BLA)foo)
__)
_[1] => Array
__(
___[0] => blabla(bla)blabla(bbllaa)
___[1] => bla(BLA)foo
__)
)
И всё было бы превосходно, если бы не необходимость в качестве ограничителей использовать не '(' и ')', а, например, '{[' и ']}', т.е. ограничители в длину более одного символа, а их не засунешь в символьный класс просто так, как это было сделано выше -- (?>[^()]+).
То есть, проблема состоит в том, чтобы создать подмаску, которая воспринимала бы все строки, в которых не содержатся сочетания символов '{[' или ']}', т.е. чтобы строки 'abcabc', 'abc[{abc', 'ab{c[abc', 'a[}b{c[abc' и т.п. проходили проверку, а 'abc{[abc', '{[abcabc', 'abcabc{[', 'abca]}bc' итп -- нет.
Давайте думать сообща, а то мозг уже скрипит.
P.S. Подозреваю, что это как-то можно легко сделать с помощью lookbehind и/или lookahead assertions, но мыслей нет, захват в моих экспериментах происходит не так, проблемы то с жадностью, то с совпадением только в конце подмаски и т.п.
P.P.S. http://www.pcre.org/pcre.txt -- мегадокумент (кроме всего прочего, например, можно узнать много интересного про рекурсивные подшаблоны, да и вообще 95% этого документа нигде в мануалах не цитируется).
В документации по пхп есть момент, описывающий получение содержимого скобок верхнего уровня с учётом парных скобок внутри.
Исходя из этого материала, получение выражения описывается так (с модификатором PCRE_EXTENDED), пока просто обратите внимание на выделение:
"\( ( (?: (?>[^()]+) | (?R) )*) \)", а если не оптимизировать, то так: "\( ( (?: [^()]+ | (?R) )*) \)".
Таким образом из строки "head (blabla(bla)blabla(bbllaa)) asdasd (bla(BLA)foo) tail" при использовании preg_match_all мы получим:
Array
(
_[0] => Array
__(
___[0] => (blabla(bla)blabla(bbllaa))
___[1] => (bla(BLA)foo)
__)
_[1] => Array
__(
___[0] => blabla(bla)blabla(bbllaa)
___[1] => bla(BLA)foo
__)
)
И всё было бы превосходно, если бы не необходимость в качестве ограничителей использовать не '(' и ')', а, например, '{[' и ']}', т.е. ограничители в длину более одного символа, а их не засунешь в символьный класс просто так, как это было сделано выше -- (?>[^()]+).
То есть, проблема состоит в том, чтобы создать подмаску, которая воспринимала бы все строки, в которых не содержатся сочетания символов '{[' или ']}', т.е. чтобы строки 'abcabc', 'abc[{abc', 'ab{c[abc', 'a[}b{c[abc' и т.п. проходили проверку, а 'abc{[abc', '{[abcabc', 'abcabc{[', 'abca]}bc' итп -- нет.
Давайте думать сообща, а то мозг уже скрипит.
P.S. Подозреваю, что это как-то можно легко сделать с помощью lookbehind и/или lookahead assertions, но мыслей нет, захват в моих экспериментах происходит не так, проблемы то с жадностью, то с совпадением только в конце подмаски и т.п.
P.P.S. http://www.pcre.org/pcre.txt -- мегадокумент (кроме всего прочего, например, можно узнать много интересного про рекурсивные подшаблоны, да и вообще 95% этого документа нигде в мануалах не цитируется).