regex replace - podmíněné nahrazení rubrika: Programování: PHP
Mějme text v kterém jsou nějakými oddělovači určeny 4 skupiny. Pokud se první skupina rovná druhé tak bych chtěl vypsat třetí skupinu, pokud jsou různé tak čtvrtou skupinu. To celé v tom textu může být samozřejmě vícekrát.
Například z:
'fdlkg jfdklgj fdkl <<xxx==xxx??aaa%%bbb>> gjfkl jgfdlkgj <<xxx==yy??ddd%%eee>> fdsklgj fdsklgj fdklgjf'
bych chtěl ziskat
'fdlkg jfdklgj fdkl aaa gjfkl jgfdlkgj eee fdsklgj fdsklgj fdklgjf'
Jsem to schopen napsat pomocí preg_replace_callback
$s = 'fdlkg jfdklgj fdkl <<xxx==xxx??aaa%%bbb>> gjfkl jgfdlkgj <<xxx==yy??ddd%%eee>> fdsklgj fdsklgj fdklgjf'; $s = preg_replace_callback('/\\<\\<(.*)\\=\\=(.*)\\?\\?(.*)\\%\\%(.*)\\>\\>/U', function ($matches) { return ($matches[1]===$matches[2]?$matches[3]:$matches[4]); }, $s); echo $s;
Ale něco mi našeptává, že by to mělo jít i jen pomocí preg_replace, akorát to asi neumím uchopit za ten správný konec.
Ty oddělovače ['<<', '==', '??', '%%', '>>'] si v principu můžu zvolit jiné, ale to asi jedno.
------------ Řešení
$re = '/\<\<(.*)\=\=(\1)\?\?(.*)\%\%(.*)\>\>|\<\<(.*)\=\=(.*)\?\?(.*)\%\%(.*)\>\>/U'; $str = 'fdlkg jfdklgj fdkl <<xxx==xxx??aaa%%bbb>> gjfkl jgfdlkgj <<xxx==yy??ddd%%eee>> fdsklgj fdsklgj fdklgjf'; $subst = '$3$8'; $result = preg_replace($re, $subst, $str);
Principiálně - jsou tam dva podobné výrazy oddělená | buď to sežere ten první nebo až ten druhý.
Každý načítá ty čtyři skupiny oddělené těmi oddělovači
V tom prvním je zabudováno, že ta druhá skupina musí být stejná jako ta první ... to je to \1
V případě, že se provede ten první tak dám do nahrazení tu třetí grupu (then) z té první části
V případě, že se provede ten druhý tak dám do nahrazení tu čtvrtou grupu (else) z té druhé části, tj. celkově osmou grupu
Online ukázka: https://regex101.com/r/nhAR6W/2
Teď to nevyzkouším, ale nešlo by něco takového? :
\<\<(.*(==)?){2}\?\?(.*)\%\%.*\>\> | \<\<(.*(==).*)\?\?.*\%\%(.*)\>\>
Tzn. když se to chytne na 1. část (před |) bude tam část za ??, když se chytne 2. (za |) část bude tam část za %%. Ale je to od boku, chce to testnout.
Pro zobrazení všech 3 odpovědí se prosím přihlaste:
Nebo se přihlaste jménem a heslem:
Komentáře