Autor Zpráva
nethor
Profil
Zdravim, mám takovýhle regulár:
mb_internal_encoding("UTF-8"); 
mb_regex_encoding("UTF-8");
echo preg_replace('~LocalAddress~',"D:\_www\Project\N-2016-10-13\2016\class\Db.php"," text <b>LocalAddress</b> text ");    
// výstup:   text D:\_www\Project\N-2016-10-13�6\class\Db.php text 
Po nahrazení mi mrší část kolem \201, nevím přesně proč, bude to asi něco kole mb (UTF-8) , zkoušel jem i různé modifikátory, bezvýsledně.
(Nepřišel jsem ani na to, jak adresu manuálně escapovat.)

Jak na to?
Jan Tvrdík
Profil
echo preg_replace(
    '~LocalAddress~',
    "D:\\_www\\Project\\N-2016-10-13\\2016\\class\\Db.php",
    " text <b>LocalAddress</b> text "
);
nethor
Profil
Jan Tvrdík:
To ale problematickou sekvenci vystřihne: // výstup: D:\_www\Project\N-2016-10-1316\class\Db.php
Jan Tvrdík
Profil
nethor:
Máš pravdu jsem se na to pořádně nepodíval. Je potřeba to napsat jako

echo preg_replace(
    '~LocalAddress~',
    "D:\\\\_www\\\\Project\\\\N-2016-10-13\\\\2016\\\\class\\\\Db.php",
    " text <b>LocalAddress</b> text "
);

protože zpětná lomítka mají speciální význam jak v PHP řetězci, tak v tom PCRE výrazu pro náhradu, viz dokumentace.
nethor
Profil
No jo, to funguje, zkoušel jsem napsat funkci pro úpravu replacementu (..ale používat k úpravě replacementu fci preg_ replace je už dost na hlavu).

Problém je úplně jinde.
Při testování jsem zjistil, že
$String = "D:\_www\Project\N-2016-10-13\2016\class\Db.php"    ;
echo "<br>String = ".$String;
// vrací: String = D:\_www\Project\N-2016-10-13�6\class\Db.php
$String = 'D:\_www\Project\N-2016-10-13\2016\class\Db.php'    ;    
echo "<br>String = ".$String;
// vrací: String = D:\_www\Project\N-2016-10-13\2016\class\Db.php

V replacementu tedy stačí použít jenoduché apostrofy místo uvozovek.
Jan Tvrdík
Profil
nethor:
Nestačí, tím se sice zbavíš toho, že ve dvojitých uvozovkách se interpretuje \201 jako byte \x81, ale i tak má zpětné lomítko v řetězci zvláštní význam, tj. ani

echo preg_replace(
    '~LocalAddress~',
    'D:\\_www\\Project\\N-2016-10-13\\2016\\class\\Db.php',
    " text <b>LocalAddress</b> text "
);

ani

echo preg_replace(
    '~LocalAddress~',
    'D:\_www\Project\N-2016-10-13\2016\class\Db.php',
    " text <b>LocalAddress</b> text "
);

nebude fungovat. I s jednoduchýma uvozovka je třeba to zapsat jako

echo preg_replace(
    '~LocalAddress~',
    'D:\\\\_www\\\\Project\\\\N-2016-10-13\\\\2016\\\\class\\\\Db.php',
    " text <b>LocalAddress</b> text "
);
nethor
Profil
... no stejně tam ale něco nesedí, v praxi to nejde použít, adresu beru jako jednu z hodnot debug_backtrace(), a načítám ji rovnou do proměnné, takže žádné apostrofy nepřicházejí v úvahu.

funkce preg_replace se tenhle problém zřejmě vůbec netýká, protože echo "\201"; vrací také zmršeninu.
Jen nevím, jak to přenastavit.

Edit:
Jan Tvrdík:
Jo to je pravda, jsou to 2 různé problémy. Jen mě nenapadá, jakou funkcí escapovat replacement. (ten bývá různý, takže manuálně to nejde.)
Davex
Profil
nethor:
načítám ji rovnou do proměnné, takže žádné apostrofy nepřicházejí v úvahu
V tom případě je si to dobré rozepsat:
$path = "D:\\_www\\Project\\N-2016-10-13\\2016\\class\\Db.php";
// nebo
$path = 'D:\\_www\\Project\\N-2016-10-13\\2016\\class\\Db.php';
// v proměnné $path bude D:\_www\Project\N-2016-10-13\2016\class\Db.php

$pattern = "~LocalAddress~";
$subject = " text <b>LocalAddress</b> text ";

// úprava pro použití v preg_replace - nahradí jedno \ za dvě \\
$replacement = str_replace("\\", "\\\\", $path);

echo preg_replace($pattern, $replacement, $subject);
Jan Tvrdík
Profil
Davex, nethor:
Nebo ještě obecněji

// nahradí jedno \ za dvě \\ a $ za \$
$replacement = addcslashes($path, '$\\');

Viz phpfashion.com/escapovani-definitivni-prirucka#toc-regularni-vyraz
nethor
Profil
Jan Tvrdík:
$replacement = addcslashes($path, '$\\'); je přesně fce, kterou jsem potřeboval.
Děkuju.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: