Помогите с регулярным выражением (разбор переменной на части)

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

Статус темы:
Закрыта.
Модераторы: xpert13
  1. farm

    farm

    Регистр.:
    8 июн 2006
    Сообщения:
    536
    Симпатии:
    105
    Есть переменная которая может содержать записи такого формата:

    В тексте могут быть цифры, двоеточия, кавычки и скобочки ().
    Но, значки # и @ уникальны, повторяються только по 2 раза, как разделители

    Что необходимо:
    - разбить эту переменную на 3 переменных

    1ая - текст до первого # или @
    2ая - текст между # и # или @ и @
    3я - текст после второго # или @(то что между [])

    И еще - если переменная не в нужном формате, т.е нет четкого совпадения структуры

    или например тегов не пара, а только один - то такую переменную пропускаем и не обрабатываем.
     
  2. fastpars

    fastpars Создатель

    Регистр.:
    7 апр 2010
    Сообщения:
    23
    Симпатии:
    7
    Начнём с простого

    PHP:

    preg_match_all
    ("~(([0-9]*(([0-9:\"'a-z]*)#([0-9:\"'a-z]*)#([0-9]*))(?U)[0-9:\"'a-z]*)|([0-9]*(([0-9:\"'a-z]*)@([0-9:\"'a-z]*)@([0-9]*))(?U)[0-9:\"'a-z]*))~i",            'aaa#bbb#123xxx@zzz@987aaa#bbb#123xxx@zzz@987aaa#bbb#123xxx@zzz@987aaa#bbb#123xxx@zzz@987',$m);
    echo('<pre>');
    print_r($m);

    Array
    (
    [0] => Array
    (
    [0] => aaa#bbb#123
    [1] => xxx@zzz@987
    [2] => aaa#bbb#123
    [3] => xxx@zzz@987
    [4] => aaa#bbb#123
    [5] => xxx@zzz@987
    [6] => aaa#bbb#123
    [7] => xxx@zzz@987
    )

    [1] => Array
    (
    [0] => aaa#bbb#123
    [1] => xxx@zzz@987
    [2] => aaa#bbb#123
    [3] => xxx@zzz@987
    [4] => aaa#bbb#123
    [5] => xxx@zzz@987
    [6] => aaa#bbb#123
    [7] => xxx@zzz@987
    )

    [2] => Array
    (
    [0] => aaa#bbb#123
    [1] =>
    [2] => aaa#bbb#123
    [3] =>
    [4] => aaa#bbb#123
    [5] =>
    [6] => aaa#bbb#123
    [7] =>
    )

    [3] => Array
    (
    [0] => aaa#bbb#123
    [1] =>
    [2] => aaa#bbb#123
    [3] =>
    [4] => aaa#bbb#123
    [5] =>
    [6] => aaa#bbb#123
    [7] =>
    )

    [4] => Array
    (
    [0] => aaa
    [1] =>
    [2] => aaa
    [3] =>
    [4] => aaa
    [5] =>
    [6] => aaa
    [7] =>
    )

    [5] => Array
    (
    [0] => bbb
    [1] =>
    [2] => bbb
    [3] =>
    [4] => bbb
    [5] =>
    [6] => bbb
    [7] =>
    )

    [6] => Array
    (
    [0] => 123
    [1] =>
    [2] => 123
    [3] =>
    [4] => 123
    [5] =>
    [6] => 123
    [7] =>
    )

    [7] => Array
    (
    [0] =>
    [1] => xxx@zzz@987
    [2] =>
    [3] => xxx@zzz@987
    [4] =>
    [5] => xxx@zzz@987
    [6] =>
    [7] => xxx@zzz@987
    )

    [8] => Array
    (
    [0] =>
    [1] => xxx@zzz@987
    [2] =>
    [3] => xxx@zzz@987
    [4] =>
    [5] => xxx@zzz@987
    [6] =>
    [7] => xxx@zzz@987
    )

    [9] => Array
    (
    [0] =>
    [1] => xxx
    [2] =>
    [3] => xxx
    [4] =>
    [5] => xxx
    [6] =>
    [7] => xxx
    )

    [10] => Array
    (
    [0] =>
    [1] => zzz
    [2] =>
    [3] => zzz
    [4] =>
    [5] => zzz
    [6] =>
    [7] => zzz
    )

    [11] => Array
    (
    [0] =>
    [1] => 987
    [2] =>
    [3] => 987
    [4] =>
    [5] => 987
    [6] =>
    [7] => 987
    )

    )
     
    farm нравится это.
  3. farm

    farm

    Регистр.:
    8 июн 2006
    Сообщения:
    536
    Симпатии:
    105
    Пробую так

    <?php
    //$str ='aaa#bbb#123xxx@zzz@987aaa#bbb#123xxx@zzz@987aaa#bbb#123xxx@zzz@987aaa#bbb#123xxx@zzz@987';

    $str ='Привет # как дела # [1.01.2010]';

    if (preg_match_all("~(([0-9]*(([0-9:\"'a-z]*)#([0-9:\"'a-z]*)#([0-9]*))(?U)[0-9:\"'a-z]*)|([0-9]*(([0-9:\"'a-z]*)@([0-9:\"'a-z]*)@([0-9]*))(?U)[0-9:\"'a-z]*))~i", $str, $match))
    {
    $first = $match[1];
    $second = $match[2];
    }
    echo "$first";

    echo('<pre>');
    print_r($match);
    ?>

    Ничего не выводиться
     
  4. Alix

    Alix

    Регистр.:
    27 янв 2008
    Сообщения:
    234
    Симпатии:
    84
    Проблема в не совсем корректной постановке задачи - нужно было указать формат числа(дата и число - разные вещи :). Попробуйте этот рег эксп

    PHP:
    preg_match_all('/(.*?)(#|@)(.*?)(#|@)\s*\[(.*?)\]/i'$str$matches);

    print_r($matches);
     
    farm нравится это.
  5. fastpars

    fastpars Создатель

    Регистр.:
    7 апр 2010
    Сообщения:
    23
    Симпатии:
    7
  6. costic

    costic Писатель

    Регистр.:
    17 май 2009
    Сообщения:
    8
    Симпатии:
    4
    если правильно понял задачу, то разделители обязательно должны быть одинаковыми, на требования к тексту тоже внимание не обратили, и последний раздел - это ж цифры, поэтому лучше подправить так:
    Код:
    /([\d\w\:\"\(\)]+?)(#|@)([\d\w\:\"\(\)]+?)\2\[(\d+?)\]/i
    т.е. нужно заменить определение второго разделителя на обратную ссылку на первый разделитель и более точно указать требования к каждому разделу
     
    farm нравится это.
  7. diavolic

    diavolic

    Регистр.:
    17 мар 2010
    Сообщения:
    522
    Симпатии:
    102
    а понаворотили то...

    PHP:
    $out explode ("@"$value);
    print_r ($out);
     
  8. farm

    farm

    Регистр.:
    8 июн 2006
    Сообщения:
    536
    Симпатии:
    105
    В продолжение топика:

    Вот извелекли мы регуляркой дату из строки
    $data = $match[5][0];

    //выводим инфу где дата равна сегодняшней дате (т.е на сегодня)
    $todaydate = date ("d.m.Y");
    if ($todaydate == $data) {
    тут вывод инфы
    }


    Как теперь вывести остальные темы на ближайшие 7 дней, исключая сегодня?
    Т.е должно получиться:

    сегодня 03.10.2010
    тут строки которые содержат 03.10 (т.е сегодня)

    На этой неделе:
    инфа на ближайшие 7 дней от сегодняшней даты (строки сегодняшнего дня не в ключаем)
     
  9. pitkina

    pitkina

    Регистр.:
    1 апр 2007
    Сообщения:
    253
    Симпатии:
    176
    можно в цикле генерировать дату прошлого дня(по формату) и тут же ее использовать для вывода
    и так 7 раз
    PHP:
    //$data = '03.10.2010';

    for($i=1;$i<=7;$i++) {
    $w_date date("d.m.Y",strtotime("{$data} - {$i} days"));

    // используем $w_date    
    }
     
    farm нравится это.
  10. farm

    farm

    Регистр.:
    8 июн 2006
    Сообщения:
    536
    Симпатии:
    105
    Спасибо работает, только нужно не за прошлую, а за будущую не делю. - поменять на + в строчке:
    PHP:
    - {$idays
    Все работает как нужно, но теперь встал вопрос как разделить данные из основного массива на 2 части:
    - массив данных за сегодня
    - массив данных на 7 дней вперед

    А то получаеться вперемешку сегодня и будущие дни.
    Вот какой код сейчас есть:
    PHP:
    {
    $str =$lastx['title'];
    if (
    preg_match_all('/(.*?)(#|@)(.*?)(#|@)\s*\[(.*?)\]/i'$str$match)) 
    {
     
    $one $match[1][0];  
     
    $two $match[3][0];  
     
    $data $match[5][0];  
    }  
    //Выводим за сегодня
    $todaydate date ("d.m.Y");
    if (
    $todaydate == $data) {
      echo 
    "$one";
     echo 
    "$two - $data";
    }
    //Создаем даты на 7 дней
    $datas "$todaydate"
    for(
    $i=1;$i<=7;$i++) { 
    $w_date date("d.m.Y",strtotime("{$datas} + {$i} days")); 
    //Выводим на неделю
    if ($data == $w_date) {
      echo 
    "$one";
     echo 
    "$two - $data";
    }
    }

    }
    В данном случаем инфа выводиться вперемешку, а хотелось бы разбить на 2 блока
     
Статус темы:
Закрыта.