preg_replace ausserhalb von [ ] eckigen klammern

megatom

Mitglied
Aloah !
Ich suche jetzt schon seit Stunden nach einer Lösung Text der sich NICHT innerhalb von eckigen Klammern befindet zu ersetzen.
Sprich : text text bla text text [ text bla text text ] text bla text ->
bla soll durch blub ersetzt werden, es sei denn es befindet sich innerhalb der eckigen Klammern !
Ich krieg es einfach nicht hin :(
Das ist mein bisheriger Ansatz :
PHP:
$text = preg_replace('/[^\[]('.$name.')[^\]]/', "***", $original_text);
 
Probier mal Folgendes:
PHP:
$text = preg_replace('/([^\x5B]*)'.preg_quote($name).'([^\x5D]*)/', '\1***\2', $original_text);
 
Aloah !
Danke erstmal, aber ...
Deine Funktion macht aus :
text text bla text text [ text bla text text ] text bla text text =>
text text blub text text [ text bla text text ] text blub text text | genauso wie sie soll.
ABER :
aus
text text bla text text [ text bla text text ] text bla text text
text text bla text text [ text bla text text ] text bla text text
macht sie :
text text blub text text [ text bla text text ] text bla text text
text text blub text text [ text bla text text ] text blub text text

und je mehr text dsa wird desto öfter "vergisst" er manche ... oder ersetz dann plötzlich sogar eins in den Klammern :(
 
Mein erster Gedanke war:

PHP:
error_reporting(E_ALL);

$string = "
text text bla text text [ text1 bla text text ] text bla text text 
text text [bla text] text [ text2 bla text text ] text bla text text 
";

// inhalt von [ string ] suchen
$pattern = '/\[.*?\]/';
preg_match_all($pattern, $string, $klammern);

// string an [ und ] teilen
$array = preg_split($pattern, $string, -1);

// ersetzen und neu zusammensetzen
for($i = 0; $i < count($array); $i++ ) {
   $array[$i] = str_replace('bla', 'blub', $array[$i]);
   if ( isset($klammern[0][$i])) $array[$i] .= $klammern[0][$i];
}

echo implode('', $array);

Vielleicht geht es auch einfacher.
 
Eine andere Variante:
PHP:
$parts = preg_split('/(\x5B[^\x5D]+\x5D)/s', $original_text, null, PREG_SPLIT_DELIM_CAPTURE);
$text = '';
foreach( $parts as $part ) {
	if( $part{0} == '[' ) {
		$text .= $part;
	} else {
		$text .= str_replace($name, '***', $part);
	}
}
var_dump($text);
 
Aloah !
Super das scheint einwandfrei zu klappen !
Eine letzte Frage noch:
Wie kann ich das noch dazu bringen, dass es INcasesensitive ist ?
 
Aloah !
PHP Version 4.4.4 ...
Habs mit strtolower versucht, aber da macht er mir auch das ersetzte Wort klein :(
 
Zuletzt bearbeitet:
PHP:
if (!function_exists('str_ireplace')  {
  function str_ireplace($search,$replace,$subject) {
    $token = '^[[term^]';
    $haystack = strtolower($subject);
    $needle = strtolower($search);
    while (($pos=strpos($haystack,$needle))!==FALSE)  {
      $c++;
      $subject = substr_replace($subject,$token,$pos,strlen($search));
      $haystack = substr_replace($haystack,$token,$pos,strlen($search));
    }
    while (($pos=strpos($subject,$token))!==FALSE)  {
      $subject = substr_replace($subject,$replace,$pos,strlen($token));
    }
    return $subject;
  }
}

Versuchs mal damit.
War das neueste Kommentar auf der Funktionsseite von [phpf]str_ireplace[/phpf]. In den Kommentaren lohnt sich immer ein kleiner Blick.

Allerdings ist zu beachten, dass solche Userimplementierungen immer langsamer sind als die in C geschriebenen Originalfunktionen von PHP.
 
Zurück