Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Помогите с регулярным выражением


Автор: dm9 14.1.2005, 23:22
Использую PCRE.

Как можно описать такую штуку: "любая строка, внутри которой не содержится подстрока 'qweqweqwe'"?

smile

Автор: Mal Hack 14.1.2005, 23:28
(^qweqweqwe)

Автор: dm9 14.1.2005, 23:36
Хм.

А можешь написать ф-цию для замены на "!" подстрок "12<что-то>34" строки "12qwe34 12rty34 12uio34". Условие замены - <что-то> не содержит строку "qwe" и не содержит пробелов.

То есть надо получить "12qwe34 ! !"
Добавлено @ 23:37
Точнее, не ф-цию, а рег. выражение.

Автор: Mal Hack 14.1.2005, 23:53
Код

<?php

$str = "12qwe34 12rty34 12uio34";
$str = preg_replace( "#(\d+[^qwe^\s]+?\d+)#U" , "!" , $str );
print $str;

?>

Автор: dm9 15.1.2005, 00:00
Mal Hack, твоё выражение не заменит строку 12ewq34.

Мне надо именно строку qwe, а не три символа q, w, e.

Автор: Mal Hack 15.1.2005, 00:18
Код

<?php

function repl( $full , $str )
 {
  if( $str != "qwe" )
   {  return "!";  }
  else
   {  return $full;  }
 }

$str = "12qwe34 12rty34 12ewq34";

$str = preg_replace( "#\d+([^\d]+)\d+#e" , "repl( \"\\0\" , \"\\1\" )" , $str );

print $str;

?>

Автор: dm9 15.1.2005, 00:23
Понял, спасибо.

Автор: Mal Hack 15.1.2005, 00:25
Стоп. Наврал...
"#\d+([^\d]+)\d+#e"
Надо:
"#\d+([^\d^\s]+)\d+#e"

Автор: dm9 15.1.2005, 00:28
Не важно, я понял. Я думал, можно без ф-ции обойтись как-то.

Автор: Mal Hack 15.1.2005, 00:28
Вот так... "#\d+(\w+?)\d+#e"
Сорри smile
Че-то глючу уже...

Автор: dm9 15.1.2005, 00:28
В смысле, без доп. ф-ции repl.

Автор: Mal Hack 15.1.2005, 00:29
Цитата(dm9 @ 15.1.2005, 00:28)
В смысле, без доп. ф-ции repl.

не получится, т.к. ^ отрицание не применимо к (), а только к классам [], а это - набор, а не последовательность.

Автор: Secandr 15.1.2005, 10:48
а что если просто проверять есть ли эта строка?

Автор: dm9 15.1.2005, 10:52
Не понимаю. Если применительно к вышеуказанному примеру, какой предложишь код?

Автор: Secandr 15.1.2005, 14:03
Цитата(dm9 @ 15.1.2005, 00:22)
Как можно описать такую штуку: "любая строка, внутри которой не содержится подстрока 'qweqweqwe'"?

Код

foreach($string as $v){
if (stripos($v,'qweqweqwe')===false){print $v."\n";}
}

Автор: Mal Hack 15.1.2005, 15:17
Цитата(Secandr @ 15.1.2005, 14:03)
stripos

Только PHP5.

Автор: Secandr 15.1.2005, 15:21
Mal Hack не принципиально, идея понятна?

Автор: Mal Hack 15.1.2005, 15:24
Secandr
у него же там числа вокруг, и я так понимаю, что числа могут быть разные... Это все-таки он как пример дал.

Автор: Secandr 15.1.2005, 15:47
смысл: ищем строку содержащую бла бла бла, а в условии ставим не smile

Автор: dm9 15.1.2005, 16:34
На самом деле, полностью задачу можно поставить так:

Вычленить блоки, начало которых такое:
{IF LALALA}
Конец такой:
{ENDIF}
И при этом чтобы не было пересечений, то есть надо задать рег. выражение так, чтобы между началом и концом блока не появилось начала другого блока (блоки вложенными быть не могут).

Смотреть отсуствие открываеющейся фигурной скобки не катит, так как внутри блока могут быть выражения вида {=VALUE}.

Как все догадались, пишу парсер шаблонов...

Автор: Secandr 15.1.2005, 16:37
У нас кто-то занимался уже подобным. Или мутоген или изатоп, можно у них спросить.

Автор: dm9 15.1.2005, 16:40
Изатоп этим занимался и Мастер ещё.

Просто хочется своё написать, чтобы язык прочувствовать. Я на PHP мало программировал.

Вообще, удивлён, что в PCRE нет такой фичи.

Автор: IZ@TOP 15.1.2005, 16:42
Цитата(dm9 @ 15.1.2005, 17:34)
{IF LALALA}
Конец такой:
{ENDIF}

Я это делал так:

Код
function FindCondition() {      // Поиск шаблонных условий.
            // Регулярное выражение для поиска условий в шаблоне.
 $Preg = "|{if\s?%?([a-zA-Z0-1_.]*?)%?\s+?([=!<>]*?)\s?%?([a-zA-Z0-1_.]*?)%?}(.*?){endif}|si";
            // При нахождении консрукций шаблонных условий они заносятся в массив ConditionMatches.
 preg_match_all($Preg, $this->Document, $this->ConditionMatches);
 if(!isset($this->ConditionMatches[0][0])) return false;
 return true;
}

Но в этой функции можно еще потом и {elseif} использовать.
Добавлено @ 16:45
Условия потом парсились таким методом:

Код
function CompileCondition(&$Template) {
            // найти все вхождения конструкций шаблонных условий.
 if(!$Template->FindCondition()) return false;
 if(sizeof($Template->ConditionMatches[0]) < 1) return true;
 for($i = 0; $i < sizeof($Template->ConditionMatches[0]); $i++) {
            // Если в условных блоках шаблона не встречаются блоки "или":
  if(!strpos($Template->ConditionMatches[4][$i], '{elseif}')) {
            // Разбор условий на составляющии и их обработка.
   $l = addslashes(trim($Template->ConditionMatches[1][$i]));
   $c = addslashes(trim($Template->ConditionMatches[2][$i]));
   $r = addslashes(trim($Template->ConditionMatches[3][$i]));
   if(isset($Template->Variables[$l])) {
    $l = $Template->Variables[$l];
   } else {
    $l = 'null';
   }
   if(isset($Template->Variables[$r])) {
    $r = $Template->Variables[$r];
   }
   if(eval('if("'.$l.'" '.$c.' "'.$r.'") { return true; } else { return false; }')) {
    $Template->Document = str_replace($Template->ConditionMatches[0][$i], $Template->ConditionMatches[4][$i], $Template->Document);
   } else {
    $Template->Document = str_replace($Template->ConditionMatches[0][$i], '', $Template->Document);
   }
  } else {        // Если в условных блоках шаблона встречаются блоки "или":
            // Разбор условий на составляющии и их обработка.
   $l = addslashes(trim($Template->ConditionMatches[1][$i]));
   $c = addslashes(trim($Template->ConditionMatches[2][$i]));
   $r = addslashes(trim($Template->ConditionMatches[3][$i]));
   if(isset($Template->Variables[$l])) {
    $l = $Template->Variables[$l];
   } else {
    $l = 'null';
   }
   if(isset($Template->Variables[$r])) {
    $r = $Template->Variables[$r];
   }
   $ex = explode('{elseif}', $Template->ConditionMatches[4][$i]);
   if(eval('if("'.$l.'" '.$c.' "'.$r.'") { return true; } else { return false; }')) {
    $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[0], $Template->Document);
   } else {
    $Template->Document = str_replace($Template->ConditionMatches[0][$i], $ex[1], $Template->Document);
   }
  }
 }
}

Автор: dm9 15.1.2005, 17:01
Цитата(IZ @ 15.1.2005, 16:42)
[a-zA-Z0-1_.]


А зачем так делать? Точка же - это любой символ, она включает всё остальное.


Вообще, не понимаю, как это работает. Я пробовал делать таким образом, правда, сразу с preg_replace. У меня из-за этого:

Цитата(IZ @ 15.1.2005, 16:42)
[a-zA-Z0-1_.]*


выдавалась вся строка целиком между мервым IF и последним ENDIF, и всё. Чуть позже получше поразбираюсь с этим выражением...

Добавлено @ 17:01
Точнее, я не так пробовал, а так:
[.]*

Автор: IZ@TOP 15.1.2005, 17:07
dm9, точку убери, это я непомню, но зачем то вставлял. У меня все на ура работает.

Автор: Secandr 15.1.2005, 17:34
точка в [] означает просто точку!

Автор: Mal Hack 15.1.2005, 17:39
Secandr
Точка это любой символ, даже в классе... Просто точка \.

Автор: Secandr 15.1.2005, 19:58
[.] - сивол точка
(.) - любой символ

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)