За последние 24 часа нас посетили 15008 программистов и 1764 робота. Сейчас ищет 1531 программист ...

Правильное экранирование символов ' и \

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

  1. vencendor

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

    С нами с:
    9 дек 2009
    Сообщения:
    11
    Симпатии:
    0
    Очень часто строки переходя их одной среды в другую нуждаются в экранированнии символов ' или ".
    самый простой способ это сделать это воспользоваться простой заменой ' на \' с помощью функции:
    Код (PHP):
    1. $str="aaaaa'aaaaaa";
    2. $str=str_replace("'","\'",$str);
    3. //   $str="aaaaa\'aaaaaa"; 
    но если этуже строку еще раз пропустить через этотже алгоритм то результат будет ошибочным
    Код (PHP):
    1. $str="aaaaa\\'aaaaaa"; 
    поскольку два слэша экранируют друг друга то ' остается.
    можно поставить регулярное выражение чтобы символ ' экранировался только если перед ним нет символа слэша. Но этот способ тоже не будет работать во всех ситуациях потомучто если есть не один а два слэша то символ ' нужно экранировать.

    Вообщем задача очень распространенная но к сожалению я не нашел элегантного решения, в итоге она сводится к :
    если перед символом ' нет слешей или их четное количество тогда нужно экранировать ' . Как указать в регулярке что количество символов четное. Или может вы решаете эту задачу както по другому?

    Буду очень благодарен за помощь, и надеюсь что решение этой проблемы еще комунибуть пригодится.
     
  2. Михаил

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

    С нами с:
    12 июл 2009
    Сообщения:
    545
    Симпатии:
    0
    Адрес:
    Bielarus
    А если
    Код (Text):
    1.  addslashes()
     
  3. vencendor

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

    С нами с:
    9 дек 2009
    Сообщения:
    11
    Симпатии:
    0
    да addslashes() справляется с задачей, но если символ уже был заэкранирован тогда получится двойное экранирование тогда появляются надписи типа "Don\'t give me". Я ищу решение которое будет срабатывать только если это необходимо для дальнейшей работы.
     
  4. Михаил

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

    С нами с:
    12 июл 2009
    Сообщения:
    545
    Симпатии:
    0
    Адрес:
    Bielarus
    А зачем их два раза экранировать? что-то я не представляю такого случая.
     
  5. vencendor

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

    С нами с:
    9 дек 2009
    Сообщения:
    11
    Симпатии:
    0
    у меня система кэша которая читает и записывает данные в файл .php. В файле php ограничителем строки является символ ', если в строке найден этот символ он экранируется. Бывают ситуации когда данные записыные в кэш выводятся, обрабатываются и потом заново записываются в файл, при этом они проходят ту же процедуру экранирования. В итоге получается двойное экранирование.
     
  6. ShamahN

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

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
    addslashes(stripslashes(stripslashes($a))) - думаю должно прокатить
    это конечно если данные каким-то непонятным образом были несколько раз заслешены
     
  7. vencendor

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

    С нами с:
    9 дек 2009
    Сообщения:
    11
    Симпатии:
    0
    Интересно :) но это не очень красиво. хотя ...
    думаю это будет быстрее работать чем какаянибуть замученая регулярка. При этом гарантирует безопасность данных и то что данные не будут нарастать лишними \.

    Огромное спасибо. Может есть еще идеи ?
     
  8. ShamahN

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

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
    есть желание узнать почему несколько раз заслешенные данные могут прийти
     
  9. ShamahN

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

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
  10. vencendor

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

    С нами с:
    9 дек 2009
    Сообщения:
    11
    Симпатии:
    0
    addslashes(stripslashes($a)) работает хорошо только пачемуто он последовательность "\\" без " ' " после, удаляет.
    тоесть строка "'sdffsd\\'fs\cvb'cvb\\\'cbvcv\\bcvb"
    превращается в "\'sdffsd\'fscvb\'cvb\\\'cbvcvbcvb"
    что в принципе не плохо, но могут оказаться ситуации в которых это сыграет злую шутку.
     
  11. ShamahN

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

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
    даже не хочу анализировать) значит не подходит
     
  12. vencendor

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

    С нами с:
    9 дек 2009
    Сообщения:
    11
    Симпатии:
    0
    можно переписать функцию stripslashes() чтобы она реагировала более адекватно на последовательность "\\"
     
  13. vencendor

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

    С нами с:
    9 дек 2009
    Сообщения:
    11
    Симпатии:
    0
    в итоге получается очень странная функция но которая удовлетворяет всем запросам:
    1. Если строка уже была экранирована то повторного процесса не происходит
    2. Обеспечивается безопасность данных если в качестве обрамления строки используется символ " ' ".

    Код (Text):
    1. function ec_slash($var) {
    2. $var=str_replace("\\'","'",$var);
    3. $var=str_replace("\\\\","\\",$var);
    4. $var=str_replace("\\","\\\\",$var);
    5. $var=str_replace("'","\\'",$var);
    6. return $var;
    7. }
     
  14. ShamahN

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

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
    никому не показывай
     
  15. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Код (PHP):
    1. $str="\'sdffsd\'fscvb\'cvb\\\'cbvcvbcvb";
    2. if(false!==strpos($str,'\\')) {
    3.     $str=preg_replace('/\\\/','',$str);
    4.     $str=addslashes($str); 
    5. } else {
    6.     $str=addslashes($str); 
    7. }
    8. echo $str;// \'sdffsd\'fscvb\'cvb\'cbvcvbcvb   
    Сразу замечу.
    Если вы будете работать с базой данных, то не используйте addslashes в целях безопасности, воспользуйтесь функцией mysqli_real_escape_string.
     
  16. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.557
    Симпатии:
    631
    Хрень какая-то, данные должны циркулировать в исходном виде и экранироваться только перед конечным выводом (в базу). Если мешают кавычки при передаче, можно конвертить в base64, так почта делает чтобы символы не портили протокол.
     
  17. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Ну так то да, хеш целее будет.
    Вообще конечно не стоит так злоупотрелять символами при передаче.
     
  18. e5cms

    e5cms Новичок

    С нами с:
    11 фев 2016
    Сообщения:
    1
    Симпатии:
    0
    Попробуйте это
    Код (PHP):
    1. function single_escape_string($v){
    2.     if(empty($v)) return '';
    3.     $a=strlen($v);
    4.     $p='';
    5.     $s=false;
    6.     $r='';
    7.     for($i=0;$i<$a;$i++){
    8.         $b=$v[$i];
    9.         if($i<$a-1) $n=$v[$i+1]; else $n='';
    10.         if($b=="'"){
    11.             if($p=="'" || $s){
    12.                 $r.=$b;
    13.                 $p='';
    14.                 $s=false;
    15.                 continue;
    16.             } else if($n!="'") $r.="'";
    17.         }
    18.         $r.=$b;
    19.         if($b=="\\" && !$s) $s=true; else $s=false;
    20.         if($s) $p=''; else $p=$v[$i];
    21.     }
    22.     return $r;
    23. }
    24.  
     
  19. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    не пробуйте это