За последние 24 часа нас посетили 15602 программиста и 1551 робот. Сейчас ищут 887 программистов ...

Preg_replace заменяет вхождения в тексте. Как этого избежать

Тема в разделе "Прочие вопросы по PHP", создана пользователем alekseyyp, 24 окт 2008.

  1. alekseyyp

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

    С нами с:
    29 сен 2008
    Сообщения:
    20
    Симпатии:
    0
    Все привет!
    Есть такой пример:
    Код (Text):
    1. $text = "test ? test ? test ?";
    2. $l = array("/\?/","/\?/", "/\?/");
    3. $list = array("1", "2?", "3");
    4. $t = preg_replace($l, $list, $text,1);
    5. echo $t;
    В результате полечаем : test 1 test 23 test ?
    А хотелось бы получить: test 1 test 2? test 3

    То есть после того как он заменил второй элемент который в значении содержит знак вопроса то при третьей замене он начинает поиск с начала строки и заменяет уже замененный вопрос. Можно ли как то указать что бы поиск продолжался с места последней замены?

    Заранее всем спасибо. :p
     
  2. alekseyyp

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

    С нами с:
    29 сен 2008
    Сообщения:
    20
    Симпатии:
    0
    Где же гуру программирования, я просто в регах не шарю поэтому и немогу дуплей отловить как это пофиксить...
     
  3. Dagdamor

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

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    alekseyyp
    preg_replace() так делать не умеет. Вызов его с массивом паттернов - это то же самое, что в цикле вызвать его несколько раз. Вроде как только функция strtr() умеет делать "умную" замену, не проходя по уже обработанному тексту второй раз.
    Спят все... после ночных смен ;)
     
  4. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    как всегда велосипед
    PHP:
    1. <?
    2. $text = "test ? test ? test ?";
    3. $list = array("1", "2?", "3");
    4. $ex=explode("?",$text);
    5. $res='';
    6. for($i=0,$c=count($ex);$i<$c;$i++) {
    7.       $res.=$ex[$i].($list[$i]?$list[$i]:"?");
    8. }
    9.  
    10. ?>
     
  5. alekseyyp

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

    С нами с:
    29 сен 2008
    Сообщения:
    20
    Симпатии:
    0
    Что то не так. делаю
    Код (Text):
    1. $text = "test ? test ? test ?";
    2. $t = strtr($text, array("?"=>"1","?"=>"2?", "?"=> "3"));
    3. echo $t;
    получаю test 3 test 3 test 3 а надо бы получить test 1 test 2? test 3

    а это я бы и сам сделал дак ресурсоемко. как же быть?
     
  6. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    ну не знаю..
    регулярки вообще медленные
     
  7. alekseyyp

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

    С нами с:
    29 сен 2008
    Сообщения:
    20
    Симпатии:
    0
    Хорошо, буду тестить на этом, просто данных оч много обрабатывать..

    Спасибо всем кто откликнулся !

    Ну если у кого появятся еще идеи пишите плс!! :)
     
  8. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    а какая стоит задача? т.е. зачем и как и что за данные нужно обрабатывать?
    Зы. Наверника в глобальном маштабе есть другое решение
     
  9. Luge

    Luge Старожил

    С нами с:
    2 фев 2007
    Сообщения:
    4.680
    Симпатии:
    1
    Адрес:
    Минск
    интересно, если я предложу
    PHP:
    1. <?php
    2. $l = array("/ \?/","/ \?/", "/ \?/");
    3. $list = array(" 1", " 2?", " 3");
    4. ?>
    т.е. заменять с пробелом, то меня заклюют? :)
     
  10. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    отдам канибалам на съедение =)))
     
  11. alekseyyp

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

    С нами с:
    29 сен 2008
    Сообщения:
    20
    Симпатии:
    0
    интересный ход :) . но думаю может быть ситуация когда и вопрос в параметрах будет стоять с пробелом. :)

    Просто вот как получается замена с продолжением от последней замены казалось бы элементарно, и что же в пхп этого никак не предусмотрели... :) . Остается пока решение от Mr.M.I.T.
     
  12. Luge

    Luge Старожил

    С нами с:
    2 фев 2007
    Сообщения:
    4.680
    Симпатии:
    1
    Адрес:
    Минск
     
  13. Luge

    Luge Старожил

    С нами с:
    2 фев 2007
    Сообщения:
    4.680
    Симпатии:
    1
    Адрес:
    Минск
    а теперь вопрос. Нафига всё это?
     
  14. alekseyyp

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

    С нами с:
    29 сен 2008
    Сообщения:
    20
    Симпатии:
    0
    ууу интересный вопрос.. а вот и ответ:

    есть запрос к примеру "SELECT * FROM table WHERE id=?"
    есть класс который их выполняет и автоматом эскейпит подстановки.
    к примеру db::query("SELECT * FROM table WHERE id=?", array(10));
    так вот эта штука и должна заменить вопросики значениями из массива параметров.
     
  15. alekseyyp

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

    С нами с:
    29 сен 2008
    Сообщения:
    20
    Симпатии:
    0
    не умную а наоборот как показал результат тупую. он не заменяет сразу а делает копии, а потом последним значением все и заполняет.
     
  16. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    нафига так делать?
    может проще сразу
    [sql]SELECT * FROM table WHERE id='10'[/sql]
    или
    [sql]SELECT * FROM table WHERE id IN ('10','11','12')[/sql]
     
  17. Luge

    Luge Старожил

    С нами с:
    2 фев 2007
    Сообщения:
    4.680
    Симпатии:
    1
    Адрес:
    Минск
    плэйсхолдеры называется. в mysqli они и так поддерживаются. Через sprintf сделай. Или DbSimple глянь
     
  18. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Через preg_replace_callback можно сделать такую замену
     
  19. Luge

    Luge Старожил

    С нами с:
    2 фев 2007
    Сообщения:
    4.680
    Симпатии:
    1
    Адрес:
    Минск
    Mr.M.I.T.
    http://phpfaq.ru/slashes#prepared
    вещь полезная. Только alekseyyp делает просто замену без учёта типов. Что убивает всю идею.


    в самом тупом случае
    PHP:
    1. <?php
    2. function EscapeQuery($query,$var,$type)
    3. {
    4.     while(strpos($query,'?')){
    5.        $variable = array_shift($var);
    6.        $query = preg_replace('/(\?)/',"'".((array_shift($type)=='s')?mysql_real_escape_string($variable):((int)$variable))."'",$query,1);
    7.     }
    8.     return $query;
    9. }
    10.  
    11. $vars = array($_GET['id'],$_GET['name']);
    12. $types = array('d','s');
    13. echo EscapeQuery("SELECT * FROM `table_name` WHERE `id`=? AND `name`=?",$vars,$types);
    14. ?>
    15.  
     
  20. PDO! PDO спасет мир!
     
  21. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    В PDO порой тоже хочется такой простой вещи ;-)
     
  22. там же есть именованные плейсхолдеры. :)
     
  23. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    а чё мне она даст? объектная модель..это хорошо, а что ещё?
     
  24. alekseyyp

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

    С нами с:
    29 сен 2008
    Сообщения:
    20
    Симпатии:
    0
    Спасибо Luge все круто