Problem mit Regulären Ausdrücken

Hi alle,

muss zurzeit für ein Projekt von einer Homepage alle <img und <a -tags auslesen.
Also dachte ich an Reguläre ausdrücke.
Meine Idee war: „<img[.^>]>" und "<a[.^]

Nur leider meinen die regulären Ausdrücke testseiten (stranges deutsch -.-), dass das so nicht matched.

Hat einer von euch ne Idee?

Warum nicht etwas dass für solche Aufgaben gedacht ist: DOMDocument?

Hallo,

deine ausdrücke verstehe ich nicht so richtig aber vielleicht so.

<img(.)> oder "<a(.)

Cheffchen

des erste ist leichter, da muss einfach der punkt raus(des ‚^‘ sagt ja schon alles auser, da brauchst ned noch den punkt, wenn ich dich richtig verstanden hab):

<img[^>]*>bei dem zweiten ist es n bissl komplizierter:
[ und ] geben ja zeichenklassen an, dh du kannst da keinen ‚ausdruck‘ reinbringen, wie des aber genau geht, dass du dann trotzdem gt und lt benutzen kannst im link weiß ich nich, ist aber sowieso glaub weniger wichtig:

<a [^>]*>.*</a>

ps @cheffchen
probier des mal aus, der sucht dann ja so lang wies geht
ausnahme: man nimmt den einen such parameter oder wies heist dazu, dass er nicht nach dem längsten(default) sondern dem kürzesten sucht

//edit
ich hab grad durch zufall festgestellt, dass es (bei mir?) so funktioniert

<a [^>]*>.*(^</a>)*</a>aber ob des immer so geht weis ich ned

Erster Regex ist unzuverlässig:

[crash@homebox ~]$ php -r 'print preg_match("#<img[^>]>#", "<img src=\"\" />");' 0

Zweiter Regex ist kaputt, wenn er wirklich alle Links haben möchte:

[crash@homebox ~]$ php -r 'preg_match("#<a [^>]*>(.*)</a>#", "<a href=\"\">test</a> foo <a href=\"\">bar</a>", $t); var_dump($t);' array(2) { [0]=> string(42) "<a href="">test</a> foo <a href="">bar</a>" [1]=> string(27) "test</a> foo <a href="">bar" }

DOMDocument ist für solche Aufgabe gemacht.

du musst noch das * machen:

<img[^>]*>dann funktionierts doch oder?

ja ok das habe ich übersehen aber mit ‚?‘ ist es glaub ich in ordnung:<a [^>]*>(.*?)</a>

tut mir leid das kenne ich nicht mal =(
ich wieß auch nicht wie sinnvoll meine ‚lösungen‘ für das problem sind, ich wollte nur die regexs richtig machen

gruß

Ja, sollte.

[code]~<img[^>]*>~i

~<a[^>]>.?~is[/code]

Der s-Modifier im zweiten Ausdruck ist wichtig. i ist weniger wichtig, aber bei HTML-Tags ist die Groß- und Kleinschreibung beliebig.

Eingabe:

[php]$input = <<<EOT
Mein Link
Mein

Link

Mein
Link

<img

src=„http://www.example.org/foo.png

/>

<![CDATA[]]>

EOT;

#[/php]

Regex:

[php]$pattern = ‚~<img[^>]*>~i‘;
$matches = array();
preg_match_all($pattern, $input, $matches);
var_dump($matches);

$pattern = ‚~<a[^>]>.?~is‘;
$matches = array();
preg_match_all($pattern, $input, $matches);
var_dump($matches);[/php]

[code]$ php -f test.php
array(1) {
[0]=>
array(5) {
[0]=>
string(44) „
[1]=>
string(46) "<img

src=„http://www.example.org/foo.png

/>"
[2]=>
string(30) „
[3]=>
string(44) „
[4]=>
string(44) „
}
}
array(1) {
[0]=>
array(4) {
[0]=>
string(47) „Mein Link
[1]=>
string(82) "Mein

Link"
[2]=>
string(26) „Not a link
[3]=>
string(47) „Mein
Link

}
}
[/code]

DOMDocument:

[php]/**

  • @see http://refactormycode.com/codes/708-innerhtml-of-a-domelement

  • @param $node DOMNode
    */
    function innerHTML($node)
    {
    $doc = new DOMDocument();
    foreach ($node->childNodes as $child) {
    $doc->appendChild($doc->importNode($child, true));
    }

    // DOMDocument seems to add a trailing newline, remove that
    return substr($doc->saveHTML(), 0, -1);
    }

// Suppress „invalid markup“ warnings
libxml_use_internal_errors(true);

$document = new DOMDocument();
$document->loadHTML($input);

$xpath = new DOMXPath($document);

foreach ($xpath->query(‚//a|//img‘) as $node) {
/* @var $node DOMElement */

switch ($node->nodeName) {
    case 'a':
        echo '------------- Found an a tag. (href='
            . $node->getAttribute('href') . ')' . "\n";
        echo '    Inner HTML: "' . innerHTML($node) . '"' . "\n";
        break;
    case 'img':
        echo '------------- Found an img tag. (src='
            . $node->getAttribute('src') . ')' . "\n";
        break;
    default:
        /* nop */
        break;
}

echo "\n";

}[/php]

[code]$ php -f test.php
------------- Found an a tag. (href=http://www.example.org/)
Inner HTML: „Mein Link“

------------- Found an a tag. (href=http://www.example.org/)
Inner HTML: "Mein

Link"

------------- Found an a tag. (href=http://www.example.org/)
Inner HTML: „Mein
Link“

------------- Found an img tag. (src=http://www.example.org/foo.png)

------------- Found an img tag. (src=http://www.example.org/foo.png)

------------- Found an img tag. (src=http://www.example.org/foo.png)

------------- Found an img tag. (src=http://www.example.org/foo.png)
[/code]

Hier wird wohl ersichtlich, dass die regulären Ausdrücke keine exakten Parser sein können.

Edit: in meinem Beispiel ist übrigens tatsächlich kein valides HTML, guck an. :slight_smile: