regexp frage

Hi,

Habe folgendes in einem String:
Code:
Test [$variable:blalba] oder auch [funktion blabla]
Ich will den Ihnalt in den eckigen Klammern bekommen.

Meine bisheige regexp sieht so aus:
PHP:
$regexp = '#[\\\]*\[([\x00-\x5C\x5E-\xFF]*[^\\\]]*)\]#';
$string = preg_replace_callback($regexp, "callback", $string);
Also darf in der Klammer alles bis auf "]" (entspricht \x5D) sein. Gut nun hätte ich aber gerne die Möglichkeit die eckigen Klammern zu escapen sprich \] nicht als Ende des Bereichs zu sehen. Dafür ist der letzte Teil da (also das [^\\\]]* ).
Klarerweise darf ein escaptes \] hier nur am Ende der Klammern stehen, es soll aber überall stehen dürfen.

Hoffe ihr verzeiht mir die lange Erklärerei ;)
Wie baue ich also das ^\\\] in die erste Charactergruppe so ein, dass so ein \] überall stehen darf?

Habe es schon mit Dingen wie
[^\\\]\x00-\x5C\x5E-\xFF]*
probiert, aber da scheitert es scheinbar daran, dass \ und ] ja 2 Zeichen sind; Ich müsste die irgendwie zusammenfassen können...in der PHP-Dokumentation habe ich darüber aber nichts finden können (http://at2.php.net/manual/de/reference.pcre.pattern.syntax.php)

Hoffe ihr wisst Rat.

mfg
visp
 
Original von vis.p
Ich will den Ihnalt in den eckigen Klammern bekommen.

Wieso nicht einfach so?
PHP:
$string="Test [$variable:blalba] oder auch [funktion blabla]";

preg_match_all('#\[(.*)\]#Um', $string, $ausgabe);


print_r($ausgabe[1]);
 
Also RegExen sind schon eine dolle Sache, man hackt ein paar Sonderzeichen in die Tastatur und es kommt ein gültiger Ausdruck raus. Nur lesen kann's keiner...

Naja, Spaß beiseite, ich würde die Ausdrücke aber zumindest so einfach wie möglich fomulieren. Bei deinem komischen Ausdruck fange ich nicht mal an zu versuchen, da durchzusehen. Wenn du lediglich Inhalte in eckigen Klammern matchen willst, dann geht's das auch ganz primitiv mit einer Zeichenklasse "alles außer ...":

PHP:
preg_replace ( '#\[([^\]]*)\]#', $wodurch, $worin );

oder alternativ auch mit dem ungreedy-Modifier, wie Mackz sagt.

Nun willst du innerhalb der Klammer also auch noch eckige Klammern erlauben, solange sie denn escapet sind. Das wird so einfach nix, da du eben eine Bedingung einbauen müsstest, dass ein bestimmtes Zeichen nur erlaubt ist, wenn ein anderes direkt davor kommt.

Als pragmatische Lösung würde ich hier einfach wählen, dass du alle Zeichenketten '\]' vor dem preg_replace_callback()-Aufruf durch ein anderes Zeichen ersetzt, welches sonst in dieser Zeichenkette nicht vorkommen darf. In etwa so:

PHP:
$string="Test [$variable:bla\]lba] oder auch [funktion blabla]";

$temp_string = str_replace ( '\]', '§', $string );

preg_replace_callback ( '#\[([^\]]*)\]#', 'callback', $temp_string);

In der Callback-Funktion kannst du das ganze dann ja zurücksubstituieren.
 
Moinsen,

statt dem schon erwähnten str_replace verfahren könnte man auch die dafür gedachten regex funktionen nutzen :D

Code:
(?<!xxx)
Negiert das angegebene Pattern und wirkt sich auf das nachfolgende aus.

Beispiel: (?<!text1)text2
Trifft auf eine Zeichenkette zu, die "text2" enthält, aber nur, wenn "text1" nicht davor kommt.

sollte dann so aussehen:
Code:
\[(.*?)(?<!\\)\]

ps: (.*) verhält sich gierig, ist als für diesen zweck nicht zu gebrauchen. (.*?) ist hier nötig.

MfG
 
Hi,
vielen Dank für die Antworten

Ich hab jetzt folgende Regexp genommen:
Code:
$regexp ='#[\\\]*\[(.*?)(?<!\\\)\]#s';
$string = preg_replace_callback($regexp, "callback", $string);

Hab bei der regexp am Ende noch die Option s (PCRE_DOTALL) eingefügt, dass der Punkt auch newline "matched".

mfg visp
 
Zurück
Oben