2 mal nach URLs parsen und ersetzen

phlux

Grünschnabel
Hallo!
Ich habe folgendes Problem, ich parse in meinem PHP-Script nach folgenden Code
[http://www.eineurl.de|Beschreibung] das soll er dann nach
HTML:
<a href="http://www.eineurl.de">Beschreibung</a>
ändern, das mache ich mit folgender RegExp:
PHP:
$output = preg_replace("%\[(http://www\.|http://)([\w|\-|\_|\.|/]+)\|([\w|\-|\_|\.|/|\s]+)\]%imU", "<a href=\"$1$2\">$3</a>", $output);

Da ich aber von Natur aus ein fauler Mensch bin :-) habe ich mir überlegt einfach angegebene Urls a la http://www.ichbinfaulundnutzekeintagzumverlinken.de auch noch als <a>-verweis zu parsen, dabei hab ich mir überlegt, dass ich zuerst nach den oben genannten Schema suche & ersetze und dann gucke ob ich verweise wie http:// finde ohne einem vorangeführten " diese sind ja folglich dann noch nicht geparst, versucht habe ich also folgenden Ausdruck anzuwenden:
PHP:
$output = preg_replace("%([^\"]http://[\w|-|_|/|\.]+)%","<a href=\"$1\">$1</a>", $output);
Das doofe ist jetzt das er keine URLs erkennt die direkt am Zeilenanfang stehen, desweiteren ist er zu eifrig weil er jetzt das Leerzeichen was vor dem http:// wenn steht auch mit in das Ergebniss von $1 packt, dass liegt wohl an dem Auschluss von [^\"], denn wenn ich diesen entferne nimmt er das Leerzeichen nicht, so ich bin jetzt leider mit meinem begrenzten RegExp Latein am Ende, hoffe ihr könnt mir hier mal weiterhelfen.
Danke schonmal im vorraus!

mfg chris/phlux
 
Probier mal Folgendes:
PHP:
<?php

	$url_patterns = array(
		'http'   => "(?:http://(?:(?:(?:(?:(?:[a-zA-Z\d](?:(?:[a-zA-Z\d]|-)*[a-zA-Z\d])?)\.)*(?:[a-zA-Z](?:(?:[a-zA-Z\d]|-)*[a-zA-Z\d])?))|(?:(?:\d+)(?:\.(?:\d+)){3}))(?::(?:\d+))?)(?:/(?:(?:(?:(?:[a-zA-Z\d$\-_.+!*'(),]|(?:%[a-fA-F\d]{2}))|[;:@&=])*)(?:/(?:(?:(?:[a-zA-Z\d$\-_.+!*'(),]|(?:%[a-fA-F\d]{2}))|[;:@&=])*))*)(?:\?(?:(?:(?:[a-zA-Z\d$\-_.+!*'(),]|(?:%[a-fA-F\d]{2}))|[;:@&=])*))?)?)",
		'ftp'    => "(?:ftp://(?:(?:(?:(?:(?:[a-zA-Z\d$\-_.+!*'(),]|(?:%[a-fA-F\d]{2}))|[;?&=])*)(?::(?:(?:(?:[a-zA-Z\d$\-_.+!*'(),]|(?:%[a-fA-F\d]{2}))|[;?&=])*))?@)?(?:(?:(?:(?:(?:[a-zA-Z\d](?:(?:[a-zA-Z\d]|-)*[a-zA-Z\d])?)\.)*(?:[a-zA-Z](?:(?:[a-zA-Z\d]|-)*[a-zA-Z\d])?))|(?:(?:\d+)(?:\.(?:\d+)){3}))(?::(?:\d+))?))(?:/(?:(?:(?:(?:[a-zA-Z\d$\-_.+!*'(),]|(?:%[a-fA-F\d]{2}))|[?:@&=])*)(?:/(?:(?:(?:[a-zA-Z\d$\-_.+!*'(),]|(?:%[a-fA-F\d]{2}))|[?:@&=])*))*)(?:;type=[AIDaid])?)?)",
		'mailto' => "(?:mailto:(?:(?:[a-zA-Z\d$\-_.+!*'(),;/?:@&=]|(?:%[a-fA-F\d]{2}))+))",
	);

	$string = 'balbla bla http://example.org blabla [http://example.org/bla/|Beschreibung – blabla] blabla bla';

	preg_match('/\[(' . addcslashes($url_patterns['http'], chr(47)) . '|' . addcslashes($url_patterns['ftp'], chr(47)) . '|' . addcslashes($url_patterns['mailto'], chr(47)) . ')\|([\x20-\x7E][^\x2F]*)\]/imU', $string, $matches);
	print_r($matches);

	preg_match('/' . addcslashes($url_patterns['http'], chr(47)) . '|' . addcslashes($url_patterns['ftp'], chr(47)) . '|' . addcslashes($url_patterns['mailto'], chr(47)) . '/', $string, $matches);
	print_r($matches);

?>
 
Zuletzt bearbeitet:
Hi Gumbo!
Alles klar geht so, danke dir!
Ein paar Fragen drängen sich mir allerdings noch auf:
- Wozu dient das :? in den RexExp's
- Was bewirkt type=[AIDaid] im 2ten Feld das patterns Array
- ([\x20-\x7E][^\x2F]*) Sind das Buchstaben in Hexadezimaler Schreibweise?

Ein zwei kurze Sätze reichen schon, den Rest reime ich mir mit der Hilfe zusammen ;)
Danke dir nochmals!
 
  • Das „?:“ sorgt dafür, dass keine Rückreferenz erzeugt wird.
  • Mit der Syntax eines FTP-URLs kenne ich mich nicht aus, die obigen regulären Ausdrücke habe ich von einem kompletten regulären Ausdruck für URLs übernommen. Doch ich denke, dass der von dir erwähnte Abschnitt einen Parameter namens „type“ beschreibt, dessen Wert nur „a“, „i“ oder „d“ besitzen darf, wobei die korrekte Groß- bzw. Kleinschreibung irrelevant ist.
  • Ja, es handelt sich um eine hexadezimale Beschreibung der ASCII-Zeichen 32–126, ausgenommen des Zeichens 47.
 
Zurück