получение всех вхождений строки и замена их

пример текста

this text will be left alone ##{class1}{arg1;arg2;arg3}## some other text and
another thingie ##{Class2}{]##

В настоящее время я использую это '/\#\#\{(?P<class>.+)\}\{(?P<args>.+)\}\#\#/i' для сопоставления, но моя проблема в том, что когда это регулярное выражение встречается несколько раз, потому что оно будет соответствовать даже тексту между двумя совпадающими шаблонами.

И это результат моего регулярного выражения ##{ClassName1}{arg1;arg2;arg3}## some other random ##{class2}{}##.

Есть ли более элегантный способ извлечь ##{class1}{arg1;arg2;arg3}## и ##{Class2}{]## из строки и заменить их выходными данными соответствующих классов?

Я использую это, чтобы заменить их выводом из Class1 и Class2 с аргументами между вторым набором {}


Примечание: если второй набор {} пуст, это означает, что в класс с именем из первого набора {} не передаются никакие аргументы.


person Gabriel    schedule 29.04.2011    source источник


Ответы (1)


Проблема в том, что .+ «жадный» — он будет потреблять каждый символ, какой только может, до тех пор, пока остальная часть шаблона все еще может разрешаться.

Грязное универсальное решение состоит в том, чтобы сделать .+?, которое будет соответствовать наименьшему количеству символов, необходимых для удовлетворения остальной части шаблона, и будет работать в этом случае.

Но в любом случае предпочтительнее писать что-то более конкретное, чем .+. В вашем случае подойдет [^}]+? То есть между символами { и } может быть любое количество символов, не являющихся закрывающими }.

person VoteyDisciple    schedule 29.04.2011
comment
И последующее замечание: если вы хотите, чтобы во втором списке аргументов не было символов, потребуется [^}]* вместо [^}]+. - person VoteyDisciple; 30.04.2011
comment
поэтому я придумал это /\#\#(?P<class>\{.+?[\}]*)(?P<args>\{.+?[\}]*)\#\#/i, оно соответствует всему, что мне нужно, но <class> содержит, например, {class1}. Но это всего лишь небольшая проблема. Но перемещение \{ и [\}]* за пределы (?P<class>\{.+?[\}]*) дает мне } при совпадении со строкой {}... черт возьми эти регулярные выражения... наверное, я никогда полностью их не пойму - person Gabriel; 30.04.2011
comment
и еще одно примечание... мне пришлось использовать .+? во второй части ##{}{}##, потому что вы можете передать почти что угодно в качестве аргумента классу... но я заменил имя класса на \w+? - person Gabriel; 30.04.2011