php-resource



Zurück   PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr > Entwicklung > PHP Developer Forum
 

Login

 
eingeloggt bleiben
star Jetzt registrieren   star Passwort vergessen
 

 

 


PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Fragen zu Laravel, YII oder anderen PHP-Frameworks.

Antwort
 
LinkBack Themen-Optionen Thema bewerten
  #1 (permalink)  
Alt 19-04-2013, 12:07
tomtherock
 Registrierter Benutzer
Links : Onlinestatus : tomtherock ist offline
Registriert seit: Jun 2002
Ort: München
Beiträge: 334
tomtherock ist zur Zeit noch ein unbeschriebenes Blatt
Standard REGEX nicht geschlossene <li>

Hallo in die Runde,

nach langem brauch ich nun doch eure Hilfe bei einem Regex.

Ich möchte in einem HTML-Template unsauberes HTML bereinigen.
Natürlich hab ich mich vorab in Google und vielen Foren informiert und anscheinend sei TIDY oder beautiful soup hierfür das beste.

Leider kann ich diese nicht auf dem Webserver installieren da Managed.

Gefunden habe ich dann zumindst eine PHP Klasse ==> HTML fixer | Barattalo

Oder online welches auch mit Regex arbeitet ==> HTML FIXER - FIXER (echt super)

dieser funktioniert schon ganz gut allerdings schwächelt er bei nicht geschlossenen <li> Tags diese schließt er immer ganz am Ende beim </ul>

Deswegen wollte ich das nun selbst mit einem preg_match/preg_replace angehen.

Hier ein Beispiel HTML bei dem die offenen <li> geschlossen werden sollen:
Code:
<UL>
<LI><STRONG>1 Gewicht:&nbsp;295 g</STRONG> </li>
<LI><STRONG>2 Obermaterial aus Airmesh</STRONG>verbessert
<LI><STRONG>3 dsfsdfds dsfsdfsd</STRONG> 
<LI><STRONG>4 Obermaterial aus Airmesh</STRONG>verbessert
</ul>
Hier mein Regex Versuch:
Der RegExp-Evaluator - RegExp-Evaluator - Ergebnis

Erklärung:
(<li>)(.+?)(?!</li>)(<li>)

==> (?!</li>) ist ein versuch mit Assertions das diese Zeichenkette nicht drin vorkommen kann

Bisher gibt er mir komischerweise immer Aufzählung 1,3 zurück.
Vielleicht könnt ihr mir hier helfen.

Perfekt wäre natürlich dann mit preg_replace ==> $1 $2 </li>$4
die offenen tags automatische schließen zu lassen, wobei ich wahrscheinlich hier dann mit preg_match_all und einer schleife arbeiten muss oder?

Beste Grüße
RegEx Noob

Geändert von tomtherock (19-04-2013 um 12:10 Uhr)
Mit Zitat antworten
  #2 (permalink)  
Alt 19-04-2013, 14:24
Melewo
 Registrierter Benutzer
Links : Onlinestatus : Melewo ist offline
Registriert seit: Jan 2013
Beiträge: 365
Melewo befindet sich auf einem aufstrebenden Ast
Standard

Das habe ich bis heute auch noch nicht begriffen. Wenn ich schreibe, Ausdruck muss vorausgehen, dann wird das richtige Ergebnis geliefert. Nur die Umkehrung versagte bisher.

PHP-Code:
$pattern '~(<li>)(.+?)(?<=</li>)(\r|\n)~is'

/*
    [0] => Array
        (
            [0] => <LI><STRONG>1 Gewicht:&nbsp;295 g</STRONG> </li>
        )

    [1] => Array
        (
            [0] => <LI>
        )

    [2] => Array
        (
            [0] => <STRONG>1 Gewicht:&nbsp;295 g</STRONG> </li>
        )

    [3] => Array
        (
            [0] => 
        )
*/ 
Mit Zitat antworten
  #3 (permalink)  
Alt 19-04-2013, 14:34
tomtherock
 Registrierter Benutzer
Links : Onlinestatus : tomtherock ist offline
Registriert seit: Jun 2002
Ort: München
Beiträge: 334
tomtherock ist zur Zeit noch ein unbeschriebenes Blatt
Standard

mhhh muss doch ne Lösung geben, hab sonst wo leider nichts gefunden und selbst bekomme ich das leider nicht hin, da bin ich mit den RegEx echt überfordert...einfache Sachen gehen .
Mit Zitat antworten
  #4 (permalink)  
Alt 19-04-2013, 15:04
Melewo
 Registrierter Benutzer
Links : Onlinestatus : Melewo ist offline
Registriert seit: Jan 2013
Beiträge: 365
Melewo befindet sich auf einem aufstrebenden Ast
Standard

Es wird daran liegen, dass in 2, also in (.+?) die Zeichenfolge </li> bereits mit durchrutscht und (?<!</li>) nicht mehr greifen kann. Wenn man jetzt aber statt(.+?) eine Zeichenklasse wie ([^<>]+?)verwenden würde, so würde <STRONG> schon mit einbegriffen.

PHP-Code:
$pattern '~(<li>)(.+?)(?<!</li>)(\r\n)(<li>)~is'

/*

    [1] => Array
        (
            [0] => <LI>
        )

    [2] => Array
        (
            [0] => <STRONG>1 Gewicht:&nbsp;295 g</STRONG> </li>
                   <LI><STRONG>2 Obermaterial aus Airmesh</STRONG>verbessert
        )

*/ 
Mit Zitat antworten
  #5 (permalink)  
Alt 19-04-2013, 15:22
tomtherock
 Registrierter Benutzer
Links : Onlinestatus : tomtherock ist offline
Registriert seit: Jun 2002
Ort: München
Beiträge: 334
tomtherock ist zur Zeit noch ein unbeschriebenes Blatt
Standard

mhhh ja stimmt, oder einfach doch mit in Kombination mit preg_split/explode arbeiten. Liefert bisher noch das beste Ergebnis. Evtl. vorher noch die <ul> auf endtag prüfen und dann jedes <ul> mit explode('<li>') prüfen oder besser preg_split() falls style definitionen im <li> vorkommen.

Und danach <li> für <li> prüfen und anpassen.

PHP-Code:

preg_split
('~<li>~is')

Array
(
    [
0] => <UL>
    [
1] => STRONG>1 Gewicht:&nbsp;295 g</STRONG>
    [
2] => hfskdhfsd </li>
    [
3] => STRONG>2 Obermaterial aus Airmesh</STRONG>verbessert
    
[4] => STRONG>3 dsfsdfds dsfsdfsd</STRONG
    [
5] => STRONG>4 Obermaterial aus Airmesh</STRONG>verbessert
</ul>

Mit Zitat antworten
  #6 (permalink)  
Alt 19-04-2013, 16:32
Melewo
 Registrierter Benutzer
Links : Onlinestatus : Melewo ist offline
Registriert seit: Jan 2013
Beiträge: 365
Melewo befindet sich auf einem aufstrebenden Ast
Standard

Das wird wohl einfacher sein. Eine weitere Möglichkeit wären zwei Durchläufe. Im ersten Durchlauf überall vor <li> ein </li> einfügen (außer bei <ul> und <li>) und im zweiten Durchlauf nur doppelte </li> wieder entfernen bzw. gegen ein einfaches </li> auszutauschen.

Geändert von Melewo (19-04-2013 um 16:41 Uhr)
Mit Zitat antworten
  #7 (permalink)  
Alt 19-04-2013, 17:33
CPCoder
 Registrierter Benutzer
Links : Onlinestatus : CPCoder ist offline
Registriert seit: Dec 2010
Beiträge: 26
CPCoder befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Leider kann ich diese nicht auf dem Webserver installieren da Managed
Und wenn du an den Support schreibst, dass sie dir das Tidy-Modul nachinstallieren?
Mit Zitat antworten
  #8 (permalink)  
Alt 19-04-2013, 18:09
tomtherock
 Registrierter Benutzer
Links : Onlinestatus : tomtherock ist offline
Registriert seit: Jun 2002
Ort: München
Beiträge: 334
tomtherock ist zur Zeit noch ein unbeschriebenes Blatt
Standard

ja ist jetzt keine super brisante Sache zudem such ich immer vorwiegend Lösung welche ich für alle meine Projekte einsetzen kann ohne extra Module für PHP.

Aber denke die Klasse die ich gefunden hab in Verbindung mit der Sonderbehandlung der <li> sollte reichen.

Vielen Dank nochmal
wenn ich eine Funktion fertig hab die gut funktioniert poste ich Sie hier natürlich
Mit Zitat antworten
  #9 (permalink)  
Alt 19-04-2013, 19:29
Melewo
 Registrierter Benutzer
Links : Onlinestatus : Melewo ist offline
Registriert seit: Jan 2013
Beiträge: 365
Melewo befindet sich auf einem aufstrebenden Ast
Standard

Valide bekommst Du das auch so, zwar nicht in zwei, wie ich zuerst dachte, doch in drei Schritten. Mit den Steuerzeichen musst Du mal sehen, \n oder \r oder \r\n, doch irgendetwas davon sollten wohl eigentlich alle Systeme kennen, denke ich mir. Muss halt noch eine Bedingung erfüllt werden, dass nur zwischen <ul> und </ul> eine Änderung erfolgt, doch das sollte ja auch noch hinzubekommen sein.

PHP-Code:
$subject '<UL>
<LI><STRONG>1 Gewicht:&nbsp;295 g</STRONG> </LI>
<LI><STRONG>2 Obermaterial aus Airmesh</STRONG>verbessert
<LI><STRONG>3 dsfsdfds dsfsdfsd</STRONG> 
<LI><STRONG>4 Obermaterial aus Airmesh</STRONG>verbessert
</ul>'
;


$subject preg_replace("~\r\n~""</li>\r\n"$subject);
$subject preg_replace("~<ul></li>~i""<ul>"$subject);
$subject preg_replace("~</li></li>~i""</li>"$subject);

echo 
"Valide:\n\n".$subject."\n\n";

/* Ausgabe (Quelltextansicht)

Valide:

<ul>
<LI><STRONG>1 Gewicht:&nbsp;295 g</STRONG> </li>
<LI><STRONG>2 Obermaterial aus Airmesh</STRONG>verbessert</li>
<LI><STRONG>3 dsfsdfds dsfsdfsd</STRONG> </li>
<LI><STRONG>4 Obermaterial aus Airmesh</STRONG>verbessert</li>
</ul>

*/ 
Noch einen weiteren Schritt, um den Quelltext einheitlicher zu gestalten:

PHP-Code:
$subject preg_replace_callback("(<(.+?)>)",

    function (
$inhalt) {
    return 
"<".strtolower($inhalt[1]).">";
    },
    
$subject
);

echo 
"Einheitlicher:\n\n".$subject."\n\n";

/* Ausgabe (Quelltextansicht)

Einheitlicher:

<ul>
<li><strong>1 Gewicht:&nbsp;295 g</strong> </li>
<li><strong>2 Obermaterial aus Airmesh</strong>verbessert</li>
<li><strong>3 dsfsdfds dsfsdfsd</strong> </li>
<li><strong>4 Obermaterial aus Airmesh</strong>verbessert</li>
</ul>

*/ 

Geändert von Melewo (19-04-2013 um 19:42 Uhr)
Mit Zitat antworten
  #10 (permalink)  
Alt 19-04-2013, 20:19
Melewo
 Registrierter Benutzer
Links : Onlinestatus : Melewo ist offline
Registriert seit: Jan 2013
Beiträge: 365
Melewo befindet sich auf einem aufstrebenden Ast
Standard

Ein zusammenhängendes Beispiel, sollte eigentlich seine Aufgaben erfüllen.

PHP-Code:
<?php error_reporting(E_ALL);
  
$doc '<!DOCTYPE html>
<html>

<head>
<title>Test</title>
</head>

<body>
<h1>Test mit Liste</h1>
<UL>
<LI><STRONG>1 Gewicht:&nbsp;295 g</STRONG> </LI>
<LI><STRONG>2 Obermaterial aus Airmesh</STRONG>verbessert
<LI><STRONG>3 dsfsdfds dsfsdfsd</STRONG> 
<LI><STRONG>4 Obermaterial aus Airmesh</STRONG>verbessert
</ul>

</body>
</html>'
;

preg_match_all("~<ul>([\S\s]+?)</ul>~i"$doc$listen);

$subject $listen[0][0]; 

$subject preg_replace("~(\r\n|\r|\n)~""</li>$1"$subject);
$subject preg_replace("~<ul></li>~i""<ul>"$subject);
$subject preg_replace("~</li></li>~i""</li>"$subject);

$subject preg_replace_callback("(<(.+?)>)",

    function (
$inhalt) {
    return 
"<".strtolower($inhalt[1]).">";
    },
    
$subject
);

echo 
"Fertig:\n\n".$subject."\n\n";

/* Ausgabe (Quelltextansicht)

Fertig:

<ul>
<li><strong>1 Gewicht:&nbsp;295 g</strong> </li>
<li><strong>2 Obermaterial aus Airmesh</strong>verbessert</li>
<li><strong>3 dsfsdfds dsfsdfsd</strong> </li>
<li><strong>4 Obermaterial aus Airmesh</strong>verbessert</li>
</ul>

*/
?>
Mit Zitat antworten
  #11 (permalink)  
Alt 19-04-2013, 21:55
combie
 PHP Expert
Links : Onlinestatus : combie ist offline
Registriert seit: May 2006
Beiträge: 3.296
combie wird schon bald berühmt werden
Standard

PHP-Code:
<?php
error_reporting
(-1);
ini_set('display_errors'TRUE);

$doc '<!DOCTYPE html>
<html>

<head>
<title>Test</title>
</head>

<body>
<h1>Test mit Liste</h1>
<UL>
<LI><STRONG>1 Gewicht:&nbsp;295 g</STRONG> </LI>
<LI><STRONG>2 Obermaterial aus Airmesh</STRONG>verbessert
<LI><STRONG>3 dsfsdfds dsfsdfsd</STRONG> 
<LI><STRONG>4 Obermaterial aus Airmesh</STRONG>verbessert
</ul>

</body>
</html>'
;

$dom = new DOMDocument;
$dom->loadHTML($doc);
echo 
$dom->saveHTML();
__________________
Wir werden alle sterben

Geändert von combie (19-04-2013 um 22:03 Uhr)
Mit Zitat antworten
  #12 (permalink)  
Alt 19-04-2013, 23:49
Melewo
 Registrierter Benutzer
Links : Onlinestatus : Melewo ist offline
Registriert seit: Jan 2013
Beiträge: 365
Melewo befindet sich auf einem aufstrebenden Ast
Standard

Ganz so einfach scheint das aber wohl mit DOM auch nicht zu sein. Damit erhalte ich zwar eine valide Liste, jedoch der Inhalt der Liste wird verstümmelt ausgegeben, da die Strong-Tags aus Value entfernt werden.

PHP-Code:
$dom = new DOMDocument;
$dom->loadHTML($doc);
$liste $dom->getElementsByTagName("li");

echo 
"<ul>\n";

foreach (
$liste as $list) {

    echo 
"<li>".$list->nodeValue."</li>\n";
}
echo 
"</ul>\n";

/* Ausgabe (Quelltextansicht):

<ul>
<li>1 Gewicht: 295 g </li>
<li>2 Obermaterial aus Airmeshverbessert
</li>
<li>3 dsfsdfds dsfsdfsd 
</li>
<li>4 Obermaterial aus Airmeshverbessert
</li>
</ul>

*/ 
Edit: Was mir noch eingefallen ist, meine bisherige Variante wird versagen bzw. fehlerhafte Ergebnisse liefern, wenn sich ein Listenpunkt (Listenelement) über mehrere Zeilen erstreckt.

Zitat:
Zitat von tomtherock Beitrag anzeigen
dieser funktioniert schon ganz gut allerdings schwächelt er bei nicht geschlossenen <li> Tags diese schließt er immer ganz am Ende beim </ul>
Wird wohl einen guten Grund haben. Deine Listen scheinen nicht wirklich invalide zu sein.

Zitat:
Es ist zwar nach HTML-Standard erlaubt, das abschließende </li>-Tag wegzulassen, doch davon ist abzuraten.
SELFHTML: HTML/XHTML / Elemente zur Textstrukturierung / Listen

Zitat:
Nehmen Sie bitte zur Kenntnis das die Tags “li” und “p” nicht beendet wurden. In HTML (nicht in XHTML) ist es erlaubt auf die Tags </li> and </p> zu verzichten..so wie hier geschehen.
HTML + CSS - ein Einstieg

Geändert von Melewo (20-04-2013 um 06:22 Uhr)
Mit Zitat antworten
  #13 (permalink)  
Alt 20-04-2013, 06:22
combie
 PHP Expert
Links : Onlinestatus : combie ist offline
Registriert seit: May 2006
Beiträge: 3.296
combie wird schon bald berühmt werden
Standard

Was machst du da?
Und warum?

Das von mir gepostete Beispiel erzeugt:
HTML-Code:
<!DOCTYPE html>
<html><head><title>Test</title></head><body>
<h1>Test mit Liste</h1>
<ul><li><strong>1 Gewicht:&nbsp;295 g</strong> </li>
<li><strong>2 Obermaterial aus Airmesh</strong>verbessert
</li><li><strong>3 dsfsdfds dsfsdfsd</strong> 
</li><li><strong>4 Obermaterial aus Airmesh</strong>verbessert
</li></ul></body></html>
Und da sind alle Strong Dinger drin.
Die werden also nicht entfernt.


Du hast das schöne DOM und klöppelst das HTML trotzdem selber....
Warum nur?
__________________
Wir werden alle sterben

Geändert von combie (20-04-2013 um 06:25 Uhr)
Mit Zitat antworten
  #14 (permalink)  
Alt 20-04-2013, 06:40
Melewo
 Registrierter Benutzer
Links : Onlinestatus : Melewo ist offline
Registriert seit: Jan 2013
Beiträge: 365
Melewo befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von combie Beitrag anzeigen
Was machst du da?
Und warum?
Gute Frage, Du hast recht, ich hatte gestern das </li> am Zeilenanfang übersehen, da ich nur auf das Zeilenende geachtet hatte. Da war ich reichlich blind, so wäre es natürlich wesentlich einfacher.

Edit: Auch wenn es mit DOM wesentlich einfacher geht, doch nun greifen die Ersetzungen auch wenn sich ein Listeneintrag über mehrere Zeilen erstreckt und liefern eine formatierte Ausgabe. Zumindest funktioniert es erst einmal bei einer Liste auf einer Seite. Wenn sich mehrere Listen auf einer Seite befinden sollten, so müsste noch einiges erweitert und umgebaut werden.

PHP-Code:
<?php error_reporting(E_ALL);
  
$doc '<!DOCTYPE html>
<html>

<head>
<title>Test</title>
</head>

<body>
<h1>Test mit Liste</h1>
<UL>
<LI><STRONG>1 Gewicht: 295 g</STRONG> </LI>
<LI><STRONG>2 Obermaterial aus Airmesh</STRONG> verbessert
und der Listeneintrag erstreckt sich über mehrere Zeilen
und noch eine Zeile mehr oder so.
<LI><STRONG>3 dsfsdfds dsfsdfsd</STRONG> 
<LI><STRONG>4 Obermaterial aus Airmesh</STRONG> verbessert
</ul>
<p>Schlusszeile</p>
</body>
</html>'
;

preg_match("~(?P<beginn><!DOCTYPE.*?[\S\s]+?)(?P<liste><ul>[\S\s]+?</ul>)(?P<ende>[\S\s]+?</html>)~i"$doc$listen);

$subject $listen["liste"]; 

$subject preg_replace("~(\r\n|\r|\n)<li>~i""</li>$1<li>"$subject);
$subject preg_replace("~<ul></li>~i""<ul>"$subject);
$subject preg_replace("~(?<!</li>)(\r\n|\r|\n)</ul>~i""</li>$1</ul>"$subject);
$subject preg_replace("~</li></li>~i""</li>"$subject);
$subject preg_replace("~(\r\n)(?!</ul>)~""$1  "$subject);

$subject preg_replace_callback("(<(.+?)>)",

    function (
$inhalt) {
    return 
"<".strtolower($inhalt[1]).">";
    },
    
$subject
);

echo 
"Ausgabe:\n\n".$listen["beginn"], $subject$listen["ende"]."\n\n";

/*Ausgabe:

<!DOCTYPE html>
<html>

<head>
<title>Test</title>
</head>

<body>
<h1>Test mit Liste</h1>
<ul>
  <li><strong>1 Gewicht: 295 g</strong> </li>
  <li><strong>2 Obermaterial aus Airmesh</strong> verbessert
  und der Listeneintrag erstreckt sich über mehrere Zeilen
  und noch eine Zeile mehr oder so.</li>
  <li><strong>3 dsfsdfds dsfsdfsd</strong> </li>
  <li><strong>4 Obermaterial aus Airmesh</strong> verbessert</li>
</ul>
<p>Schlusszeile</p>
</body>
</html>
*/
?>

Geändert von Melewo (20-04-2013 um 21:16 Uhr)
Mit Zitat antworten
Antwort

Lesezeichen

Stichworte
<li>, li-tags, nicht geschlossen, regex


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Bekomm regex nicht hin strauberry PHP Developer Forum 13 28-12-2007 13:47
[REGEX] Wertangaben nicht erzwingen sagg PHP Developer Forum 2 04-07-2006 21:24
[REGEX] Regex geht nicht mehr wenn "[]" im Suchmuster daniel987 PHP Developer Forum 6 05-03-2006 21:55
Regex will nicht strauberry PHP Developer Forum 15 30-08-2004 13:23

Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre 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


PHP News

ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlicht
ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlichtDie bekannte Marktplatzsoftware ebiz-trader ist in der Version 7.5.0 veröffentlicht worden.

28.05.2018 | Berni

Wissensbestand in Unternehmen
Wissensbestand in UnternehmenLebenslanges Lernen und Weiterbilden sichert Wissensbestand in Unternehmen

25.05.2018 | Berni


 

Aktuelle PHP Scripte

PHP Server Monitor

PHP Server Monitor ist ein Skript, das prüft, ob Ihre Websites und Server betriebsbereit sind.

11.09.2018 Berni | Kategorie: PHP/ Security
PHP WEB STATISTIK ansehen PHP WEB STATISTIK

Die PHP Web Statistik bietet Ihnen ein einfach zu konfigurierendes Script zur Aufzeichnung und grafischen und textuellen Auswertung der Besuchern Ihrer Webseite. Folgende zeitlichen Module sind verfügbar: Jahr, Monat, Tag, Wochentag, Stunde Folgende son

28.08.2018 phpwebstat | Kategorie: PHP/ Counter
Affilinator - Affilinet XML Produktlisten Skript

Die Affilinator Affilinet XML Edition ist ein vollautomatisches Skript zum einlesen und darstellen der Affili.net (Partnerprogramm Netzwerk) Produktlisten und Produktdaten. Im Grunde gibt der Webmaster seine Affilinet PartnerID ein und hat dann unmittelb

27.08.2018 freefrank@ | Kategorie: PHP/ Partnerprogramme
 Alle PHP Scripte anzeigen

Alle Zeitangaben in WEZ +2. Es ist jetzt 19:11 Uhr.