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

Статус
В этой теме нельзя размещать новые ответы.

farm

Постоялец
Регистрация
7 Июн 2006
Сообщения
536
Реакции
115
Есть переменная которая может содержать записи такого формата:

текст # текст # [число]
или
текст @ текст @ [число]

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

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

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

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

текст # текст # [число]
или
текст @ текст @ [число]

или например тегов не пара, а только один - то такую переменную пропускаем и не обрабатываем.
 
Начнём с простого
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
Пробую так

<?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);
?>

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

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

print_r($matches);
 
  • Нравится
Реакции: farm
если правильно понял задачу, то разделители обязательно должны быть одинаковыми, на требования к тексту тоже внимание не обратили, и последний раздел - это ж цифры, поэтому лучше подправить так:
Код:
/([\d\w\:\"\(\)]+?)(#|@)([\d\w\:\"\(\)]+?)\2\[(\d+?)\]/i
т.е. нужно заменить определение второго разделителя на обратную ссылку на первый разделитель и более точно указать требования к каждому разделу
 
  • Нравится
Реакции: farm
а понаворотили то...

PHP:
$out = explode ("@", $value);
print_r ($out);
 
В продолжение топика:

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

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


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

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

На этой неделе:
инфа на ближайшие 7 дней от сегодняшней даты (строки сегодняшнего дня не в ключаем)
 
можно в цикле генерировать дату прошлого дня(по формату) и тут же ее использовать для вывода
и так 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
Спасибо работает, только нужно не за прошлую, а за будущую не делю. - поменять на + в строчке:
PHP:
- {$i} days

Все работает как нужно, но теперь встал вопрос как разделить данные из основного массива на 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 блока
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху