Вот тут пишу рег. выражения для обработки таких тегов: [tag param]asdf[/tag] или одинарных [tagg /]. Вот есть два рег. выражения первоедля обработки первого варианта написания, второе длявторого соответственно: PHP: preg_match_all("/(\[(\w+)[^\]]*\])(.*)(\[\/\\2\])/",$s,$a,PREG_SET_ORDER); PHP: preg_match_all('/(\[([\w]+)([^\]]*)\/\])/',$s,$a,PREG_SET_ORDER); а вотне знаю, как можно объединить их (рег. выражения)? чтобы сразу искались эти теги, пробовал так: PHP: preg_match_all('/((\[(\w+)[^\]]*\])(.*)(\[\/\\2\])) | ((\[([\w]+)([^\]]*)\/\]))/X',$s,$a,PREG_SET_ORDER); но геморно работает может кто подсказать как можно это дело объединить? Заранее благодарю
Для чего ты поставил модификатор X? Что в твоем понимании "геморно работает"? Что ты ожидал и что получил?
Первая регулярка у тебя в двойных кавычках, последняя - в одинарных. Следовательно, в последней регулярке выражение '\\2' означает косую и двойку, а не обратную ссылку. Не забывай, что в PHP одинарные и двойные кавычки - это две большие разницы. Когда ты пишешь строку в двойных кавычках, обрытные слэши сначала парсятся парсером PHP в контексте строки, а затем - парсером preg в контексте регулярного выражения. Если ты не уверен, что сможешь держать в уме оба этих преобразования, то используй одинарные кавычки для регулярок. Модификатор X включает генерацию ошибки, когда обратная черта и буква после нее не имеют какого-либо специального значения. Ты же, вероятно, хотел включить игнорирование пробелов. Для этого нужно использовать модификатор x (маленькая буква, а не большая).
Raa, да, ты прав, запамятовал с Х, да мне и сейчас кажется что надо большую... Нуда ладно, не важно, насчёт двойных\одинарных всгеда юзаю одинарные, видимо так запаился, что написал двойные. Сейчас покажу результат выполнения в виде массива: Код (Text): Array ( [0] => Array ( [0] => [p dsa] внутри тега [/p] [1] => [p dsa] внутри тега [/p] [2] => [p dsa] [3] => p [4] => внутри тега [5] => [/p] ) [1] => Array ( [0] => [loop] а это цикл;)[/loop] [1] => [loop] а это цикл;)[/loop] [2] => [loop] [3] => loop [4] => а это цикл;) [5] => [/loop] ) [2] => Array ( [0] => [b]жирный текст[/b] [1] => [b]жирный текст[/b] [2] => [b] [3] => b [4] => жирный текст [5] => [/b] ) [3] => Array ( [0] => [module name="qwe" /] [1] => [2] => [3] => [4] => [5] => [6] => [module name="qwe" /] [7] => [module name="qwe" /] [8] => module [9] => name="qwe" ) ) Вроде двойныетеги разбиваотся нормально, а одинарные нет. Регулярка и строка следующие: PHP: preg_match_all('/((\[(\w+)[^\]]*\])(.*)(\[\/\\3\]))|((\[([\w]+)([^\]]*)\/\]))/',$s,$a,PREG_SET_ORDER); Код (Text): $s = "до тега [p dsa] внутри тега [/p] после тега;) [loop] а это цикл;)[/loop]а щас будет [b]жирный текст[/b] [module name=\"qwe\" /]";
Хм... значит, обратная ссылка работает нормально? Сам уже запутался с этими косыми... )) Ну а что тебе не нравится? Как ты их хочешь разбивать?
Raa, вот последняя часть массива, там дофигапробелов, видишь их? Видимо он одинарный тег ещё пытается разбитьпервымусловием... Проверял в программе The regex coach, там показывается что то вроде Код (Text): ||||||module| name="qwe" из-за чего такое может возникать? и именно только тогда, когда объединены эти условия! Пораздельно всё хорошо,всёменяустраивает...
Нулевой элемент - это вся строка. Последующие элементы массива - это пошло содержимое скобок. Скобки нумеруются слева направо по открывающей. Во-первых, у тебя слишком много скобок. По крайней мере можешь смело снять скобки с левого и правого подвыражения. Поставь все-таки модификатор x, а то без пробелов фиг что разберешь там где скобки просто необходимы, но тебе все равно не нужно захватывать их содержимое в виде отдельного элемента массива, пиши так: '(?:...)'. Во-вторых, я так и не понял, какие части строки ты пытаешься захватить. В любом случае, такая регулярка будет помещать атрибуты тэгов с содержимым и без в разные элементы массива, поскольку сама регулярка состоит из двух разны подрегулярок, и в зависимости от случая буду срабатывать разные по счету скобки. В общем, если объяснишь, какие подстроки тебе нужно выхватывать, то могу попробовать помочь составить что-то более удобное.
Raa, что касается слешей, в двойных кавычках толькодвойной перед ссылкой ставить надо. в одинарных всё равно - один или два Самдумай от чего так,я не шарю. Ну а что касается захватываемых выражений, дак в первом моём посте жирным шрифтом выделены на второй строке что-то подобное HTML тегам
Я не это имел в виду... ну ок, давай так. Попробуй убрать все скобки, посмотри результат и скажи, то ли это, что тебе нужно.
Raa, вот тебе наглядно http://webst.natm.ru/examples/regex.php то, что я делал, первый массив - какты понимаешь получается объединённым рег.выражением, изаметь, последний элемент там много пустых подъэлементов! Второй массив это толькопервая частьрег. выражения, а третий массив это вторая частьрег. выражения, вторая и третья части меня устраивают, но почему вобъединённом массиве последний элемент содержит столько пустых подэлементов, а в третьем случае, отдельно, не содержит? ВОт это мне и не нравится, со скобками разобрался, всё как естьменя устраивает
Содержит столько пустых подэлементов, потому что первая подрегулярка не отработала, и все скобки первой половины не отработали, и за каждой скобкой закреплен ее порядковый номер, под которым и появляется элемент в подмассиве.
Пусть тебя не смущают эти пустые элементы. Просто имей в виду, что n-ый элемент подмассива соответствует n-ой скобке
Raa, меня смущает то, что скрипт тогданеработает, ибо он всё автоматомделает, 3-й элемент допустим означаетимямодуля запускаемого, 4-й - переданные параметры и это плохо! хотя можно и проверку сделать если пустой, то братьтакие то элементы Спасибо за разъяснение
Значит, чтобы параметры всегда были на своем месте, измени регулярку примерно вот так: /\[(\w+) \s* (.*?) (?: \/\] | \](.*)\[\1\])/x Не пробовал, так что возможно есть ошибка. Но в этом варианте по крайней мере параметр всегда будет на своем месте в массиве. Только здесь есть по крайней мере одна проблема. Вот два варианта строк: [tag] [tag] [/tag] [/tag] [tag] [/tag] [tag] [/tag] Как ты ни крути свою регулярку, а в одном из двух вариантов она отработает неправильно. Для того, чтобы корректно обработать такой вариант, смотри про рекурсивные регулярки (Recursive patterns).
Raa, спасибо, доехал досути дела, отредактировал практическидо совершенства Код (Text): /\[(\w+) (.*?) (?: \/\] | \](.*?)\[\/\1\])/x ТОлько объясни конструкцию (?: что-то | что-то2) этотипа так японял, идёт выбор между что-то и что-то2? я просто с рег. выражениями не особо ас Спасибо!
http://webst.natm.ru/examples/regex.php вот можешьпосмотреть на её работу, самый последний вариант работает как мне надо! Большое спасибо! Надеюсь больше багов не обнаружится!
| - это выбор () - это просто скобки (?: ) - это те же скобки, только они не делают захват, и их содержимое не появляется отдельным элементом в массиве. А вообще, все подробно в мане описано. Изучай