PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : $x durch $y ersetzen, wenn $x nicht zwischen " und " oder ' und ' oder < und > steht.


MC Breit
13.08.2004, 20:58
Hi!
Also, es geht um einen perl kompatible regex für verwendung mit preg_replace.
er sollte das zeichen x durch ein zeichen y ersetzen, aber nur wenn das zeichen x nicht zwischen " und " steht.

Jetzt ist dabei noch ein problem, dass es nicht nur zwischen " und " sondern auch zwischen ' und ', < und >, &quot; und &quot; nicht ersetzt werden darf.
Auf der anderen seite aber nur zwischen &lt;? und ?&gt; oder &lt;% und %&gt;.

Wenn noch nciht ganz verstanden, hier mal ein vorher nachher:

Davor:

&lt;html&gt;
&lt;span style="x-pos:23;"&gt;Hallo x!&lt;/span&gt;
&lt;%
&quot;hallo x&quot;&lt;br /&gt;x
$x[5] = "y";
%&gt;
&lt;?
echo "x".$x[5].'z';
//lalax
?&gt;
&lt;/html&gt;

Dannach:

&lt;html&gt;
&lt;span style="x-pos:23;"&gt;Hallo x!&lt;/span&gt;
&quot;hallo x&quot;&lt;br /&gt;
&lt;%
&quot;hallo x&quot;&lt:br /&gt;y
$y[5] = "y";
%&gt;
&lt;?
echo "x".$y[5].'z';
//lalay
?&gt;
&lt;/html&gt;


Ich weiß, das hört sich nun sehr komplitiert an, ist es aber denke cih eigendlich nicht..
Also, nochmal schnell zusammenfassung:
x wird durch y ersetzt.
Aber nur wenn x innerhalb von &lt;? und ?&gt; oder innerhalb von &lt;% und %&gt; steht.
Aber nicht wenn es zwischen ' und ', oder " und " etc. (siehe oben) steht.

Vielen dank im vorraus!
Wer sich fragt für was ich sowas bruahce, es geht darum bestimmte special chars innerhab eines schon gehighlighteten php strings zu ersetzen.


z3r0x
13.08.2004, 21:33
Meinst du so?

<?
$string = "&lt;x&gt; blah &lt;x&gt; blubb <%x%>";

$patterns[0] = "/&lt;?x?&gt;/";
$patterns[1] = "/&lt;%x%&gt;/";
$replacements[0] = "&lt;?y?&gt;";
$replacements[1] = "&lt;%y%&gt;";

echo preg_replace($patterns, $replacements, $string);
?>

Kann mit deinen % und ? Zeichen irgendwie nichts anfangen. :rolleyes:

Edit: Irgendwie hat das Board einige Zeichen aus der Variable "$string" hier im Code verschluckt...

Gruß z3r0x

MC Breit
13.08.2004, 23:42
Hi!
Nein, du ersetzt ja wieder nur einfach zwischen den zeichen bla und blubb..
da fehlt ja noch der weitaus schwierigere teil, das zwischen " und " zb nicht ersezt werden darf, also innerhalb von % und % und bla, schon richtig, aber auch innerhalb von diesen, darf zwischen " und " und ' und ' und noch ein paar nicht ersetzt werden.

Also, ich hab vorhin einmal angefangen, das ganze ohne regex anzugehen, und da hab ich jetzt eben nur diese NICHT bedingung, aber noch nciht die zwischen &lt;% und %&gt; bedingung, die du schon hast..
Hier mal mein code, wenn es interesiert:
/*****
* (string) str_creplace(str search, str replace, str string, array foribidden_chars=(",'))
* Führt ein bedingtes ersetzen von search durch replace aus.
* Dabei wird nicht zwiwschen den durch forbidden_chars gegebenen zeichen paaren ersetzt.
* forbidden_chars muss (insofern angegeben) mindestens 1 zeichen beinhalten - ansonsten sollten sie str_replace verwenden.
*/
function str_creplace($search, $replace, $str, $fchars=array('"', "'"))
{
$forbidden = NULL;
$checkstr = NULL;
$str_p1 = NULL;
$str_p2 = NULL;
$c = 0;
unset($forbidden);

for($i=0; $i<strlen($str); $i++)
{
if( !isset($forbidden) )
{
for($j=0; $j<count($fchars); $j++)
{
if(strlen($fchars[$j])>1)
{
$checkstr = substr($str, $i, strlen($fchars[$j]));
if($checkstr == $fchars[$j])
{
$forbidden = $fchars[$j];
print "Matched: {$fchars[$j]}\n";
$i = $i+strlen($fchars[$j]);
$i = $i-1;
break;
}
}
elseif($str{$i} == $fchars[$j])
{
$forbidden = $fchars[$j];
print "Matched: {$fchars[$j]}\n";
break;
}
}
if(strlen($search)>1)
{
$checkstr = substr($str, $i, strlen($search));
if($checkstr == $search)
{
print "Replace: $checkstr by $replace\n";
$str_p1 = substr($str, 0, $i);
$c = $i;
$c = $c+strlen($search);
$str_p2 = substr($str, $c);
$str = $str_p1.$replace.$str_p2;
$i = $i+strlen($replace);
$i = $i-1;
unset($c);
unset($str_p1);
unset($str_p2);
continue;
}
}
elseif($str{$i} == $search && !isset($forbidden))
{
print "Replace: $str[$i] by $replace\n";
if(strlen($replace)>1)
{
$str_p1 = substr($str, 0, $i);
$c = $i;
$c = $c+1;
$str_p2 = substr($str, $c);
$str = $str_p1.$replace.$str_p2;
$i = $i+strlen($replace);
$i = $i-1;
unset($c);
unset($str_p1);
unset($str_p2);
continue;
}
else
{
$str{$i} = $replace;
}
break;
}
}
elseif( isset($forbidden) )
{
if(strlen($forbidden)>1)
{
$checkstr = substr($str, $i, strlen($forbidden));
print "Dematching with determined str: $checkstr\n";
if($checkstr == $forbidden)
{
print "Dematched: $forbidden\n";
unset($forbidden);
$i = $i+strlen($fchars[$j]);
$i = $i-1;
}
}
if($str{$i} == $forbidden)
{
print "Dematched: $forbidden\n";
unset($forbidden);
}
}
}

return $str;
}
Der ist jetzt mal aus meiner regex ignoranz herraus entstanden, wobei ich als regex ignorant sogar denke das ein regex hier sinnvoll währe, zwecks übersicht, wie man an obigem beispiel sieht^^
Was auch interesant währe, wenn man dem regex beibringen könnte, nicht durch y zu ersetzen, sondern durch den aufruf der funktion bla(x) zu ersetzen, allerdings bezwifle ich ja das das möglich ist :-/

Ansonsten, wenn noch jemand in den regex einbauen kann, das eben zb zwischen " und " nicht ersetzt wird, wäre ich sehr dankbar, aber auhc für eine nicht regex weiterentwicklung meines ansatzes. Bis dahin verbleibend,

EmCee

MC Breit
14.08.2004, 02:03
So, meine regex ignoranz hat gesiegt, hab es ohne einen ausdruck gelöst..

Wer es wissen will, wie, der schaue hier:
<?php
$str = '&lt;html&gt;
&lt;span style="x-pos:23;"&gt;Hallo x!&lt;/span&gt;
&lt;%
&quot;hallo x&quot;&lt;br /&gt;x
$x[5] = "y";
%&gt;
&lt;?
echo "x".$x[5].\'z\';
//lalax
?&gt;
&lt;/html&gt;';
print str_cperform('in_php_replace', $str, array('&lt;?', '?&gt;'));
function in_php_replace($str)
{
$fchars = array(array('"', '"'),
array('&quot;', '&quot;'),
array("'", "'"),
array('<', '>'),
);
return str_creplace('x', 'y', $str, $fchars);
}
/*****
* (string) str_creplace(str search, str replace, str string, array foribidden_chars=(",'))
* Führt ein bedingtes ersetzen von search durch replace aus.
* Dabei wird nicht zwiwschen den durch forbidden_chars gegebenen zeichen paaren ersetzt.
* forbidden_chars muss (insofern angegeben) mindestens 1 zeichen beinhalten - ansonsten sollten sie str_replace verwenden.
*/
function str_creplace($search, $replace, $str, $fchars=array(array('"', '"')))
{
$forbidden = NULL;
$checkstr = NULL;
$str_p1 = NULL;
$str_p2 = NULL;
$c = 0;
unset($forbidden);

for($i=0; $i<strlen($str); $i++)
{
if( !isset($forbidden) )
{
for($j=0; $j<count($fchars); $j++)
{
if(strlen($fchars[$j][0])>1)
{
$checkstr = substr($str, $i, strlen($fchars[$j][0]));
if($checkstr == $fchars[$j][0])
{
$forbidden = $j;
$i = $i+strlen($fchars[$j][0]);
$i = $i-1;
break;
}
}
elseif($str{$i} == $fchars[$j][0])
{
$forbidden = $j;
break;
}
}
if(strlen($search)>1)
{
$checkstr = substr($str, $i, strlen($search));
if($checkstr == $search)
{
$str_p1 = substr($str, 0, $i);
$c = $i;
$c = $c+strlen($search);
$str_p2 = substr($str, $c);
$str = $str_p1.$replace.$str_p2;
$i = $i+strlen($replace);
$i = $i-1;
unset($c);
unset($str_p1);
unset($str_p2);
continue;
}
}
elseif($str{$i} == $search && !isset($forbidden))
{
if(strlen($replace)>1)
{
$str_p1 = substr($str, 0, $i);
$c = $i;
$c = $c+1;
$str_p2 = substr($str, $c);
$str = $str_p1.$replace.$str_p2;
$i = $i+strlen($replace);
$i = $i-1;
unset($c);
unset($str_p1);
unset($str_p2);
continue;
}
else
{
$str{$i} = $replace;
}
break;
}
}
elseif( isset($forbidden) )
{
if(strlen($fchars[$forbidden][1])>1)
{
$checkstr = substr($str, $i, strlen($fchars[$forbidden][1]));
if($checkstr == $fchars[$forbidden][1])
{
unset($forbidden);
$i = $i+strlen($fchars[$j][1]);
$i = $i-1;
}
}
if($str{$i} == $fchars[$forbidden][1])
{
unset($forbidden);
}
}
}

return $str;
}
/****
* (string) str_cperform( str function_to_call, str string array between_chars)
* Führt einen funktionsaufruf mit den zwichen die zwischen between_chars pärchen gefunden wurden
* aus, und ersetzt diese durch die rückgabe der durch function_to_call gegebenen funktion.
* diese operation wird auf dem string string druchgeführt.
*/
function str_cperform($function, $str, $bchars)
{
if(strstr($str, $bchars[0]) && strstr($str, $bchars[1]))
{
//start loop at first match of $bchars[0]
$fpos = strpos($str, $bchars[0]);
for($i=$fpos;$i<strlen($str);$i++)
{
if(($sub = substr($str, $i, strlen($bchars[0]))) == $bchars[0] )
{
$str_p1 = substr($str, 0, ($i+strlen($bchars[0])));
$str_p2 = substr($str, ($i+strlen($bchars[0])));
if( strstr($str_p2, $bchars[1]) )
{
$target = substr($str_p2, 0, strpos($str_p2, $bchars[1]));
$str = substr($str_p2, strlen($target));
$target = call_user_func($function, $target);
$res .= $str_p1.$target;
}
}
}
$res .= $str;
}
return $res;
}
system("PAUSE");
?>
Villeicht kann die funktionen ja noch jemand gebrauchen, sind auch auf alle möglichen anderen aufgaben wo etwas nur zwischen x und y aber nicht zwischen z und a ersetzt werden darf anwendbar..
bye bye

z3r0x
14.08.2004, 03:04
Haeh?

Also meiner Meinung nach, erfuellt mein Code oben alle Bedingungen die du gestellt hast.

Aber wenn du es nun auch so hinbekommen hast, ists ja in Ordnung...

Gruß z3r0x

MC Breit
14.08.2004, 06:48
Hi!
Du ersetzt x ja nur durch y wenn dies innerhalb von &lt;? und ?&gt; ist, wenn aber zb &lt;? x "x" ?&gt; da steht, sollte &lt;? y "x" ?&gt; herrauskommen, was bei dir nicht der fall ist.
Ich hab diens nicht getestet, aber so weit ich regex verstehe, naja, sollte es doch anderst sein korrigiere mich..

z3r0x
14.08.2004, 14:04
Achsoooo, jetzt komme ich langsam dahinter, was du eigentlich willst. :rolleyes:

MC Breit
14.08.2004, 19:12
Ja, eigendlich will ich innerhlab von einem String nur zwischen ein paar bestimmten zeichenfolgen ersetzen, damit zb ausserhb von php code nicht gehighliughtt wird, und innerhalb von diesem gibt es ja wieder situationen, in denen ein zeichen nicht ersetzt werden darf, zb wenn es zwischen < und > oder zwischen ' und ' steht usw..
Und darum geht es..
Das mit dem "aber nicht zwischen x und y" blicke ich aber nicht so ganz..
Und hab gemerkt das meine funktion bei mehr als 50 zeilen code dann doch ganzschön ins hängen kommt, php ist halt nicht c ;-)
Also, wenn nochmal ideen da sind, bin weiter für die regex offen, sind dann warscheinlich doch schneller als 3 sekunden :P

Messiah_of_Death
24.08.2004, 22:52
habe zur besseren Übersicht statt "y" ein "@" benutzt


das hier ist mein Output



&lt;html&gt;

&lt;span style="x-pos:23;"&gt;Hallo x!&lt;/span&gt;
&lt;%
&quot;hallo x&quot;&lt;br /&gt;@
$@[5] = "y";
%&gt;
&lt;?
echo "x".$@[5].'z';
//lala@
?&gt;
&lt;/html&gt;





<?

$fp = fopen("text", "r");

if ($fp)
{
$data = "";

while (!feof($fp))
$data .= fread($fp, 4096);

fclose($fp);

echo $data;

$ndata = "";

$pattern = array( "/(?!(.*(&lt;|\"|').*\s*.*))(x)/i",
"/(x)(?=(\[))/i");

$replace =array("@", "@");

preg_match_all($pattern, $data, $ndata);

print_r($ndata);

$ndata = preg_replace($pattern, $replace, $data);

echo $ndata;
}
?>
Text beinhaltet dein Input


hehe, danke für diese Aufgabe, hab schon lang kein RegEx mehr angefasst, war ein gutes Training (hab nur die erste Stunde in die falsche Richtung "geExt" :rolleyes: ) ;)


ehm ja , da ich dein Text net so ganz gerallt habe, hatte ich praktisch nur das hier zum testen, wenn du was längeres hättest.. und es net geht .. guck ich nochmal drüber (obwohl die Expression von mir net so schwer ist, könntest du eigentlich auch modifizieren )