Reguläre Ausdrücke: Nur nächtstes Vorkommen bzw. Zeichenkette ausschließen

ThoRr

Mitglied
Hi,

ich stehe gerade vor einem Problem mit regulären Ausdrücken. Ich bin mir sicher, dass das, was ich vorhabe, realisierbar ist, nur weiß ich nicht, wie.

Und zwar habe ich folgendes Pseudotemplate:
HTML:
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<!-- IF head -->
<head>
	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />

	<title>Untitled 1</title>
</head>
<!-- ENDIF -->

<!-- IF body -->
<body>

</body>
<!-- ENDIF -->
</html>

Hier möchte ich mittels folgendem preg_match die IFs herausfiltern:
PHP:
preg_match('/<!-- IF (.*) -->(.*)<!-- ENDIF -->/s', $subject, $matches);

Allerdings erhalte ich hiermit einige falsche Ergebnisse im $matches-Array. Das, was meinem gewünschten, nämlich dem Inhalt jeweils einer IF-Anweisung am nächsten kommt, ist Folgendes:
HTML:
<!-- IF head -->
<head>
	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />

	<title>Untitled 1</title>
</head>
<!-- ENDIF -->

<!-- IF body -->
<body>

</body>
<!-- ENDIF -->

Allerdings wird als Ende des ersten IFs das letzte ENDIF und nicht das nächste genommen. Daher muss ich diese Zeichenkette mit (.*) ausschließen. Und auch um die IF-Bedingung zu erhalten, kann ich nicht (.*) verwenden, sondern muss "-->" ausschließen. Aber wie kann man gleich eine ganze Zeichenkette ausschließen? Mit [^... geht es nicht.

LG
 
Hallo,

da hast du gleich mehrere Möglichkeiten.

Das Problem deines Ausdrucks ist die sogenannte Gier. Mit dem U - Modifier kannst du diese umkehren.
Code:
/<!-- IF (.*) -->(.*)<!-- ENDIF -->/sU

Eine weitere Möglichkeit, die Gier zu beeinflussen, ist das Hinzufügen eines Fragezeichens hinter den verwendeten Quantor.

Code:
/<!-- IF (.*?) -->(.*?)<!-- ENDIF -->/s

Um ganze Zeichenketten ausschließen zu können, solltest du dich zunächst mit der Verwendung von negative assertions vertraut machen.
 
Hi asipak4you,

vielen Dank! Sowohl mit dem U-Modifier als auch mit dem Fragezeichen funktioniert es perfekt. Danke auch für den Tip mit den negative assertions. Von sowas ähnlichem hatte ich beim Googlen gelesen - ich werd mir das nochmal genauer anschauen.

LG
 
Es funktioniert alles nahezu perfekt und ich bin inzwischen bei ELSEIFs angelangt. Allerdings habe ich hier irgendwie ein Brett vor dem Kopf. Mein Pseudotemplate sieht inzwischen folgendermaßen aus (auf Validität habe ich ausnahmsweise mal vorsichtig verzichtet :D ):
HTML:
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<!-- IF head -->
<head>
	<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
	<meta name="author" content="" />

	<title>Untitled 1</title>
</head>
<!-- ELSEIF head2 -->
<head>

</head>
<!-- ELSEIF head3 -->
<head>
	<meta />
</head>
<!-- ELSEIF head4 -->
<head>
	<meta content="" />
</head>
<!-- ELSEIF head5 -->
<head>
	<link />
</head>
<!-- ELSEIF head6 -->
<head>
	<link rel="" />
</head>
<!-- ENDIF -->

<!-- IF body -->
<body>

</body>
<!-- ENDIF -->
</html>


Hiermit möchte ich die ELSEIFs und ihre Inhalte in das $machtes_elseif-Array schreiben:
PHP:
preg_match_all('/<!-- ELSEIF (.*) -->(.*)(<!-- ELSEIF .* -->|<!-- ENDIF -->)/sU',
	$template,
	$matches_elseif);


Allerdings wird hiermit nur jede zweite ElseIf-Anweisung gefunden, was ich ja soweit auch nachvollziehen kann, da ich am Ende die nächste schon vorweggreife. Ohne die letzte Klammer geht es aber auch nicht, da ich so zwar alle Conditions aus der ersten Klammer bekomme, aber leider nicht mehr die Inhalte der zweiten.

Wie könnte ich dieses Problem lösen?
 
Zuletzt bearbeitet:
Zurück