За последние 24 часа нас посетили 16937 программистов и 1292 робота. Сейчас ищут 1470 программистов ...

Регулярные выражения

Тема в разделе "Регулярные выражения", создана пользователем Мессир, 13 авг 2006.

  1. Мессир

    Мессир Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    32
    Симпатии:
    0
    Адрес:
    Господин Великий Новгород
    Вот тут пишу рег. выражения для обработки таких тегов:
    [tag param]asdf[/tag] или одинарных [tagg /]. Вот есть два рег. выражения первоедля обработки первого варианта написания, второе длявторого соответственно:
    PHP:
    1. preg_match_all("/(\[(\w+)[^\]]*\])(.*)(\[\/\\2\])/",$s,$a,PREG_SET_ORDER);
    PHP:
    1. preg_match_all('/(\[([\w]+)([^\]]*)\/\])/',$s,$a,PREG_SET_ORDER);
    а вотне знаю, как можно объединить их (рег. выражения)? чтобы сразу искались эти теги, пробовал так:
    PHP:
    1. preg_match_all('/((\[(\w+)[^\]]*\])(.*)(\[\/\\2\])) | ((\[([\w]+)([^\]]*)\/\]))/X',$s,$a,PREG_SET_ORDER);
    но геморно работает :( может кто подсказать как можно это дело объединить? Заранее благодарю
     
  2. Raa

    Raa Активный пользователь

    С нами с:
    28 июл 2006
    Сообщения:
    209
    Симпатии:
    0
    Для чего ты поставил модификатор X?
    Что в твоем понимании "геморно работает"? Что ты ожидал и что получил?
     
  3. Raa

    Raa Активный пользователь

    С нами с:
    28 июл 2006
    Сообщения:
    209
    Симпатии:
    0
    Первая регулярка у тебя в двойных кавычках, последняя - в одинарных. Следовательно, в последней регулярке выражение '\\2' означает косую и двойку, а не обратную ссылку. Не забывай, что в PHP одинарные и двойные кавычки - это две большие разницы. Когда ты пишешь строку в двойных кавычках, обрытные слэши сначала парсятся парсером PHP в контексте строки, а затем - парсером preg в контексте регулярного выражения. Если ты не уверен, что сможешь держать в уме оба этих преобразования, то используй одинарные кавычки для регулярок.

    Модификатор X включает генерацию ошибки, когда обратная черта и буква после нее не имеют какого-либо специального значения. Ты же, вероятно, хотел включить игнорирование пробелов. Для этого нужно использовать модификатор x (маленькая буква, а не большая).
     
  4. Мессир

    Мессир Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    32
    Симпатии:
    0
    Адрес:
    Господин Великий Новгород
    Raa, да, ты прав, запамятовал с Х, да мне и сейчас кажется что надо большую... Нуда ладно, не важно, насчёт двойных\одинарных всгеда юзаю одинарные, видимо так запаился, что написал двойные. Сейчас покажу результат выполнения в виде массива:
    Код (Text):
    1.  
    2. Array
    3. (
    4.     [0] => Array
    5.         (
    6.             [0] => [p dsa] внутри тега [/p]
    7.             [1] => [p dsa] внутри тега [/p]
    8.             [2] => [p dsa]
    9.             [3] => p
    10.             [4] =>  внутри тега
    11.             [5] => [/p]
    12.         )
    13.  
    14.     [1] => Array
    15.         (
    16.             [0] => [loop] а это цикл;)[/loop]
    17.             [1] => [loop] а это цикл;)[/loop]
    18.             [2] => [loop]
    19.             [3] => loop
    20.             [4] =>  а это цикл;)
    21.             [5] => [/loop]
    22.         )
    23.  
    24.     [2] => Array
    25.         (
    26.             [0] => [b]жирный текст[/b]
    27.             [1] => [b]жирный текст[/b]
    28.             [2] => [b]
    29.             [3] => b
    30.             [4] => жирный текст
    31.             [5] => [/b]
    32.         )
    33.  
    34.     [3] => Array
    35.         (
    36.             [0] => [module name="qwe" /]
    37.             [1] =>
    38.             [2] =>
    39.             [3] =>
    40.             [4] =>
    41.             [5] =>
    42.             [6] => [module name="qwe" /]
    43.             [7] => [module name="qwe" /]
    44.             [8] => module
    45.             [9] =>  name="qwe"
    46.         )
    47.  
    48. )
    Вроде двойныетеги разбиваотся нормально, а одинарные нет. Регулярка и строка следующие:
    PHP:
    1. preg_match_all('/((\[(\w+)[^\]]*\])(.*)(\[\/\\3\]))|((\[([\w]+)([^\]]*)\/\]))/',$s,$a,PREG_SET_ORDER);
    Код (Text):
    1. $s = "до тега [p dsa] внутри тега [/p] после тега;) [loop] а это цикл;)[/loop]а щас будет [b]жирный текст[/b] [module name=\"qwe\" /]";
     
  5. Raa

    Raa Активный пользователь

    С нами с:
    28 июл 2006
    Сообщения:
    209
    Симпатии:
    0
    Хм... значит, обратная ссылка работает нормально? Сам уже запутался с этими косыми... :)))

    Ну а что тебе не нравится? Как ты их хочешь разбивать?
     
  6. Мессир

    Мессир Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    32
    Симпатии:
    0
    Адрес:
    Господин Великий Новгород
    Raa, вот последняя часть массива, там дофигапробелов, видишь их? Видимо он одинарный тег ещё пытается разбитьпервымусловием... Проверял в программе The regex coach, там показывается что то вроде
    Код (Text):
    1. ||||||module| name="qwe"
    из-за чего такое может возникать? и именно только тогда, когда объединены эти условия! Пораздельно всё хорошо,всёменяустраивает...
     
  7. Мессир

    Мессир Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    32
    Симпатии:
    0
    Адрес:
    Господин Великий Новгород
    да, и ещё почему то по два раза исходная строка написана в готовом массиве...
     
  8. Raa

    Raa Активный пользователь

    С нами с:
    28 июл 2006
    Сообщения:
    209
    Симпатии:
    0
    Нулевой элемент - это вся строка. Последующие элементы массива - это пошло содержимое скобок. Скобки нумеруются слева направо по открывающей.

    Во-первых, у тебя слишком много скобок. По крайней мере можешь смело снять скобки с левого и правого подвыражения. Поставь все-таки модификатор x, а то без пробелов фиг что разберешь :) там где скобки просто необходимы, но тебе все равно не нужно захватывать их содержимое в виде отдельного элемента массива, пиши так: '(?:...)'.

    Во-вторых, я так и не понял, какие части строки ты пытаешься захватить. В любом случае, такая регулярка будет помещать атрибуты тэгов с содержимым и без в разные элементы массива, поскольку сама регулярка состоит из двух разны подрегулярок, и в зависимости от случая буду срабатывать разные по счету скобки. В общем, если объяснишь, какие подстроки тебе нужно выхватывать, то могу попробовать помочь составить что-то более удобное.
     
  9. Мессир

    Мессир Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    32
    Симпатии:
    0
    Адрес:
    Господин Великий Новгород
    Raa, что касается слешей, в двойных кавычках толькодвойной перед ссылкой ставить надо. в одинарных всё равно - один или два;) Самдумай от чего так,я не шарю.
    Ну а что касается захватываемых выражений, дак в первом моём посте жирным шрифтом выделены на второй строке;) что-то подобное HTML тегам ;)
     
  10. Raa

    Raa Активный пользователь

    С нами с:
    28 июл 2006
    Сообщения:
    209
    Симпатии:
    0
    Я не это имел в виду... ну ок, давай так. Попробуй убрать все скобки, посмотри результат и скажи, то ли это, что тебе нужно.
     
  11. Мессир

    Мессир Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    32
    Симпатии:
    0
    Адрес:
    Господин Великий Новгород
    Raa, вот тебе наглядно http://webst.natm.ru/examples/regex.php то, что я делал, первый массив - какты понимаешь получается объединённым рег.выражением, изаметь, последний элемент там много пустых подъэлементов! Второй массив это толькопервая частьрег. выражения, а третий массив это вторая частьрег. выражения, вторая и третья части меня устраивают, но почему вобъединённом массиве последний элемент содержит столько пустых подэлементов, а в третьем случае, отдельно, не содержит? ВОт это мне и не нравится, со скобками разобрался, всё как естьменя устраивает;)
     
  12. Raa

    Raa Активный пользователь

    С нами с:
    28 июл 2006
    Сообщения:
    209
    Симпатии:
    0
    Содержит столько пустых подэлементов, потому что первая подрегулярка не отработала, и все скобки первой половины не отработали, и за каждой скобкой закреплен ее порядковый номер, под которым и появляется элемент в подмассиве.
     
  13. Raa

    Raa Активный пользователь

    С нами с:
    28 июл 2006
    Сообщения:
    209
    Симпатии:
    0
    Пусть тебя не смущают эти пустые элементы. Просто имей в виду, что n-ый элемент подмассива соответствует n-ой скобке
     
  14. Мессир

    Мессир Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    32
    Симпатии:
    0
    Адрес:
    Господин Великий Новгород
    Raa, меня смущает то, что скрипт тогданеработает, ибо он всё автоматомделает, 3-й элемент допустим означаетимямодуля запускаемого, 4-й - переданные параметры;) и это плохо! хотя можно и проверку сделать если пустой, то братьтакие то элементы;) Спасибо за разъяснение;)
     
  15. Raa

    Raa Активный пользователь

    С нами с:
    28 июл 2006
    Сообщения:
    209
    Симпатии:
    0
    Значит, чтобы параметры всегда были на своем месте, измени регулярку примерно вот так:

    /\[(\w+) \s* (.*?) (?: \/\] | \](.*)\[\1\])/x

    Не пробовал, так что возможно есть ошибка. Но в этом варианте по крайней мере параметр всегда будет на своем месте в массиве. Только здесь есть по крайней мере одна проблема. Вот два варианта строк:

    [tag] [tag] [/tag] [/tag]
    [tag] [/tag] [tag] [/tag]

    Как ты ни крути свою регулярку, а в одном из двух вариантов она отработает неправильно. Для того, чтобы корректно обработать такой вариант, смотри про рекурсивные регулярки (Recursive patterns).
     
  16. Мессир

    Мессир Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    32
    Симпатии:
    0
    Адрес:
    Господин Великий Новгород
    Raa, спасибо, доехал досути дела, отредактировал практическидо совершенства :D
    Код (Text):
    1. /\[(\w+) (.*?) (?: \/\] | \](.*?)\[\/\1\])/x
    ТОлько объясни конструкцию (?: что-то | что-то2) этотипа так японял, идёт выбор между что-то и что-то2? я просто с рег. выражениями не особо ас;)
    Спасибо!
     
  17. Мессир

    Мессир Активный пользователь

    С нами с:
    31 июл 2006
    Сообщения:
    32
    Симпатии:
    0
    Адрес:
    Господин Великий Новгород
    http://webst.natm.ru/examples/regex.php вот можешьпосмотреть на её работу, самый последний вариант ;) работает как мне надо! Большое спасибо! Надеюсь больше багов не обнаружится!
     
  18. Raa

    Raa Активный пользователь

    С нами с:
    28 июл 2006
    Сообщения:
    209
    Симпатии:
    0
    | - это выбор
    () - это просто скобки
    (?: ) - это те же скобки, только они не делают захват, и их содержимое не появляется отдельным элементом в массиве. А вообще, все подробно в мане описано. Изучай :)