Рекурсивное регулярное выражение в PHP с именами переменных

Я пытаюсь сделать движок bbcode-ish для своего сайта. Но дело в том, что не ясно, какие коды доступны, потому что коды сделаны пользователями. И вдобавок ко всему, все это должно быть рекурсивным.

Например:

Hello my name is [name user-id="1"]
I [bold]really[/bold] like cheeseburgers

Это простые, и я добился того, чтобы это сработало.

Теперь проблема в том, что происходит, когда два из этих кодов находятся позади друг друга:

I [bold]really[/bold] like [bold]cheeseburgers[/bold]

Или внутри друг друга

I [bold]really like [italic]cheeseburgers[/italic][/bold]

Эти коды также могут иметь атрибуты

I [bold strengh="600"]really like [text font-size="24px"]cheeseburgers[/text][bold]

Следующий работал довольно хорошо, но не хватает в рекурсивной части (? R)

(?P<code>\[(?P<code_open>\w+)\s?(?P<attributes>[a-zA-Z-0-1-_=" .]*?)](?:(?P<content>.*?)\[\/(?P<code_close>\w+)\])?)

Я просто не знаю, куда поместить рекурсивный тег (? R).

Также система должна знать, что в этой строке здесь

I [bold]really like [italic]cheeseburgers[/italic][/bold] and [bold]football[/bold]

2 «кодовых объекта»:

1. [bold]really like [italic]cheeseburgers[/italic][/bold]

а также

2. [bold]football[/bold]

… и содержание первого

really like [italic]cheeseburgers[/italic]

в котором опять есть код

[italic]cheeseburgers[/italic]

какой контент

cheeseburgers

Я искал в Интернете в течение двух дней, и я не могу понять это.

Я думал о чем-то вроде этого:

  1. Найдите что-то вроде [**** attr = «foo»], где атрибуты являются необязательными, и сохраните его в группе захвата.
  2. Посмотрите, есть ли где-нибудь закрывающий тег (может быть и необязательным)
  3. Если закрывающий тег существует, все между двумя тегами должно быть сохранено как группа захвата контента, которая затем должна снова пройти ту же процедуру.

Я надеюсь, что есть некоторые специалисты по регулярным выражениям, которые готовы мне помочь. 🙁

Спасибо!

РЕДАКТИРОВАТЬ

Поскольку это может быть трудно понять, вот входные данные и ожидаемый результат:

Входные данные:

[heading icon="rocket"]I'm a cool heading[/heading][textrow][text]<p>Hi!</p>[/text][/textrow]

Я хотел бы иметь массив как

array[0][name] = heading
array[0][attributes][icon] = rocket
array[0][content] = I'm a cool heading
array[1][name] = textrow
array[1][content] = [text]<p>Hi!</p>[/text]
array[1][0][name] = text
array[1][0][content] = <p>Hi!</p>

1

Решение

Написав несколько систем разбора BBCode, я могу предложить НЕ использовать только регулярные выражения. Вместо этого вам следует разобрать текст.

Как вы это делаете, зависит от вас, но в качестве общей идеи вы хотели бы использовать что-то вроде strpos найти первый [ в вашей строке, затем проверьте, что следует за ним, чтобы увидеть, выглядит ли он как тег BBCode, и обработайте его, если так. Затем найдите [ снова начиная с того места, где вы оказались.

Это имеет определенные преимущества, такие как возможность проверять каждый код и пропускать его, если он недействителен, а также обеспечивать соблюдение правильного порядка закрытия тегов ([bold][italic]Nesting![/bold][/italic] следует считать недействительным) и иметь возможность предоставлять значимые сообщения об ошибках пользователю, если что-то не так (возможно, недопустимый параметр), потому что синтаксический анализатор точно знает, что происходит, тогда как регулярное выражение выдаст что-то неожиданное и потенциально опасное.

Это может быть больше работы (или меньше, в зависимости от вашего навыка с регулярным выражением), но оно того стоит.

2

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

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

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector