php.de

Zurück   php.de > Webentwicklung > PHP Einsteiger > PHP Tipps 2008

 
 
LinkBack Themen-Optionen Thema bewerten
Alt 13.12.2008, 02:50  
Erfahrener Benutzer
 
Registriert seit: 19.03.2007
Beiträge: 176
BlackWolf ist zur Zeit noch ein unbeschriebenes Blatt
Standard RegExp: Negierte Back References?

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
BlackWolf ist offline  
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 13.12.2008, 10:21  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.657
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

Zitat:
So, das Problem: Diese "Back References", also das \1, funktionieren nicht in eckigen Klammern.
Du musst IMHO "\\1" schreiben, sonst wird der Backslash nicht erkannt...?
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline  
Alt 13.12.2008, 13:52  
Erfahrener Benutzer
 
Registriert seit: 19.03.2007
Beiträge: 176
BlackWolf ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Zitat von dr.e. Beitrag anzeigen
Du musst IMHO "\\1" schreiben, sonst wird der Backslash nicht erkannt...?
Nein, weil das Backslash in dem Fall Teil der Syntax ist.
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.
BlackWolf ist offline  
Alt 13.12.2008, 15:15  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.657
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

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); 
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline  
Alt 13.12.2008, 15:52  
Erfahrener Benutzer
 
Registriert seit: 19.03.2007
Beiträge: 176
BlackWolf ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Zitat von dr.e. Beitrag anzeigen
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); 
ne, $1 hatte ich auch schon probiert, tuts leider nich.
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
BlackWolf ist offline  
Alt 13.12.2008, 16:08  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.657
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

Zitat:
Ich hätte es halt gerne habt das ich sowohl " als auch ' verwenden kann, aber das scheint nicht möglich zu sein.
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.

Zitat:
Danke auf jeden Fall!
Gerne.
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline  
Alt 13.12.2008, 16:15  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.989
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Hmm, na wozu brauchst Du denn Klassen:

Code:
preg_match('/^([a-z0-9\_\-\.]+)[ ]{0,}=[ ]{0,}([\"\'])(.+)\2;/iUms',$test,$matches);
oder ähnlich (ungetestet) sollte mit ungreedy doch auch gehen.
Zudem kannst Du auch beide Fälle als oder darstellen:
Code:
...(?:\"([^\"]+)\"|\'([^\']+)\')...
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist offline  
Alt 13.12.2008, 16:16  
Erfahrener Benutzer
 
Registriert seit: 19.03.2007
Beiträge: 176
BlackWolf ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Zitat von dr.e. Beitrag anzeigen
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.


Gerne.
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:
("|')(.+)\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.
BlackWolf ist offline  
Alt 13.12.2008, 16:24  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.989
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

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
)

*/ 
Man kann sogar escapte Delimiter eibauen mit einem Oder Statement.
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist offline  
Alt 13.12.2008, 16:31  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.657
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

Zitat:
Das aber nur so am Rande ...
Danke für den Hinweis, man lernt nie aus.
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline  
 


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Scriptsuche RegExp: TelNrn aus String extrahieren scream479 Scriptbörse 1 04.09.2008 17:08
[Erledigt] REGEXP und Collations Datenbanken 2 14.03.2006 14:22
Bräuchte hilfe bei einem Regexp Chr!s PHP Tipps 2005 1 27.01.2005 16:39

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
regex backreference, negierter regex, regexp backreferences php, backreferences, regex backreferences, backreferences preg_match, regular expression backreference eingeschlossen, regexp \/ims\, regexp /ims, php regex backward ungreedy, regexp * aber nicht, backreferences regex, regexp back references, regex backreference beispiel, php regex backreference

Alle Zeitangaben in WEZ +2. Es ist jetzt 20:31 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum