Tja, mal wieder treiben mich reguläre Ausdrücke zum Wahnsinn.
Ich will einen regulären Ausdrück für folgendes. Ich habe z.B. eine Zeile ähnlich einer Variablenzuweisung in PHP, sowas wie
muh = "eek";
Was ich jetzt möchte ist eek auslesen. Das an sich ist nicht so schwer. Problematisch wird es dann aber wenn folgendes dazu kommt:
1) eek kann auch ein mehrzeiliger Text sein (newlines sind keine Begrenzungen)
2) " können auch durch ' ersetzt werden
3) Nach der Zeile können noch ähnliche Zeilen auftauchen, ich muss also aufpassen das nicht zuviel gematcht wird
So ... ich hatte es jetzt probiert mit folgendem Regexp:
/^[a-z0-9\._-]+ *= *("|\')[^\1]+\1 *;/ims
Um euch das lesen etwas zu vereinfachen:
^[a-z0-9\._-]+: Am Anfang des Strings kommt der "Variablenname" der nur aus den angegeben zeichen bestehen darf
Danach kommen beliebig viele Whitespaces
Dann ein =
Dann wieder beliebige Whitespaces
Dann entweder ein " oder '
Jetzt soll jedes beliebige Zeichen kommen außer " oder ', je nachdem was gematcht wurde
Dann ein " oder ', je nachdem was gematcht wurde
Wieder mal beliebig viele Whitespaces
Schließlich ein ;
So, das Problem: Diese "Back References", also das \1, funktionieren nicht in eckigen Klammern.
Lange Rede kurzer Sinn: Gibt es dafür ein Workaround oder hat jemand evtl. sogar einen besseren Ansatz für mein Problem? Das Problem ist ganz einfach das ich verbieten muss das " oder ' (je nachdem was eben eingesetzt wird um die Zeichenkette zu begrenzen) in der Zeichenkette vorkommen, da ich sonst schwachsinnige Ergebnisse kriege.
der U-Modifier ist leider auch keine Lösung, da ich später noch escaping einbauen will. Und bei U würde sowas wie
muh = "ee\"k";
nur bis vor das k gematcht werden.
Naja: Ideen?
Danke
BlackWolf
Ankündigung
Einklappen
Keine Ankündigung bisher.
RegExp: Negierte Back References?
Einklappen
Neue Werbung 2019
Einklappen
X
-
RegExp: Negierte Back References?
Stichworte: -
-
Escapezeichen gehen über ODER und Wiederholung:
*kram* irgendwo hatte ich das schon mal umgesetzt: muß ich nachliefern...
[edit]
Nur mal exemplarisch für die DblQuotes:Mit escapten backslashes wirds wieder ein Stück komplizierter.Code:preg_match_all ('#\"((?:(?:\\\")|[^\\"]+)+)\"#U' , $test , $aElements);
-
Danke für den Hinweis, man lernt nie aus.Das aber nur so am Rande ...
Einen Kommentar schreiben:
-
Man kann sogar escapte Delimiter eibauen mit einem Oder Statement.PHP-Code:$test ="sdjklfhd = 'abcd\"';";
preg_match('/^([a-z0-9\_\-\.]+)[ ]{0,}=[ ]{0,}([\"\'])(.+)\2;/iUms',$test,$matches);
print_r($matches);
$test ='sdjklfhd = "abcd\'sadsa";';
preg_match('/^([a-z0-9\_\-\.]+)[ ]{0,}=[ ]{0,}([\"\'])(.+)\2;/iUms',$test,$matches);
print_r($matches);
/*
Array
(
[0] => sdjklfhd = 'abcd"';
[1] => sdjklfhd
[2] => '
[3] => abcd"
)
Array
(
[0] => sdjklfhd = "abcd'sadsa";
[1] => sdjklfhd
[2] => "
[3] => abcd'sadsa
)
*/
Einen Kommentar schreiben:
-
Naja, geben sie in dem Sinne schon, nämlich eben über Back References. Aber Back References lassen sich eben nicht in Verbindung mit NOT verwenden, das ist das Problem. Sowas z.B. geht aber schon:Zitat von dr.e. Beitrag anzeigenDas Problem dabei ist das ODER. Es gibt demnach keine Zusage darüber, dass, falls beim ersten Versuch ein " verwendet wurde, dies auch beim zweiten Mal erfolgt. Man muss sich entweder entscheiden oder auf strpos() & substr() umsteigen. Regexps geben das in dieser Form nicht her.
Gerne.
("|')(.+)\1
das würde "muh" und 'muh' matchen, aber nicht "muh'
Das aber nur so am Rande ...
Aber werde dann wohl einfach festlegen das " verwendet werden müssen.
Wenn ich das Topic aber schon grad offen hab nämlich noch ne kleine Frage: Hat jemand ne Idee wie ich ein escape zeichen einbaun kann? Im Klartext:
"ha"llo"
soll nicht gematcht werden aber
"ha\"llo"
eben schon.
Ich hatte es versucht mit
[^[^\\]"]+
das wollte aber nicht.
Einen Kommentar schreiben:
-
Hmm, na wozu brauchst Du denn Klassen:
oder ähnlich (ungetestet) sollte mit ungreedy doch auch gehen.Code:preg_match('/^([a-z0-9\_\-\.]+)[ ]{0,}=[ ]{0,}([\"\'])(.+)\2;/iUms',$test,$matches);
Zudem kannst Du auch beide Fälle als oder darstellen:
Code:...(?:\"([^\"]+)\"|\'([^\']+)\')...
Einen Kommentar schreiben:
-
Das Problem dabei ist das ODER. Es gibt demnach keine Zusage darüber, dass, falls beim ersten Versuch ein " verwendet wurde, dies auch beim zweiten Mal erfolgt. Man muss sich entweder entscheiden oder auf strpos() & substr() umsteigen. Regexps geben das in dieser Form nicht her.Ich hätte es halt gerne habt das ich sowohl " als auch ' verwenden kann, aber das scheint nicht möglich zu sein.
Gerne.Danke auf jeden Fall!
Einen Kommentar schreiben:
-
ne, $1 hatte ich auch schon probiert, tuts leider nich.Zitat von dr.e. Beitrag anzeigenHi,
dann versuche nochmal statt "\1" ein "$1" zu schreiben. Bei mir tut folgender Code seinen Dienst:
PHP-Code:$test = 'fo9o="b
a
mein )=(/&%$/()=Itest
r";';
preg_match('/^([a-z0-9\_\-\.]+)[ ]{0,}=[ ]{0,}\"([^\"]+)\";/iUms',$test,$matches);
echo print_r($matches);
Dein Code wäre mein Ausweich-Code gewesen, dann muss die rechte Seite vom Gleichheitszeichen halt in " eingeschlossen sein, ' sind dann tabu.
Ich hätte es halt gerne habt das ich sowohl " als auch ' verwenden kann, aber das scheint nicht möglich zu sein.
Danke auf jeden Fall!
mfg
Einen Kommentar schreiben:
-
Hi,
dann versuche nochmal statt "\1" ein "$1" zu schreiben. Bei mir tut folgender Code seinen Dienst:
PHP-Code:$test = 'fo9o="b
a
mein )=(/&%$/()=Itest
r";';
preg_match('/^([a-z0-9\_\-\.]+)[ ]{0,}=[ ]{0,}\"([^\"]+)\";/iUms',$test,$matches);
echo print_r($matches);
Einen Kommentar schreiben:
-
Nein, weil das Backslash in dem Fall Teil der Syntax ist.Zitat von dr.e. Beitrag anzeigenDu musst IMHO "\\1" schreiben, sonst wird der Backslash nicht erkannt...?
Die Back-Reference funktioniert auch über \1, nur eben nicht in den eckigen Klammern, was aber eben auch das PHP-Manual sagt. Das gibt es nicht.
Die Frage ist wie ich mein Problem gelöst kriege.
Einen Kommentar schreiben:
-
Du musst IMHO "\\1" schreiben, sonst wird der Backslash nicht erkannt...?So, das Problem: Diese "Back References", also das \1, funktionieren nicht in eckigen Klammern.
Einen Kommentar schreiben:

Einen Kommentar schreiben: