acid_ice: RegEx, URL bearbeiten

morsche,

ich habe mich gerade schon durchs archiv geschlagen, aber mir fehlt es wohl hinsichlich regulärer ausdrücke an der fähigkeit, diese auf andere problematiken zu übertragen.
daher hier eine kurze frage:

ich möchte in einer html datei alle verzeichnis- und linkangaben abändern, die relativ sind. mein ansatz war folgender:

$element =~ s/src="^http://"/src="$erweiterung$1"/gi;

ich will praktisch nur dort pfade ersetzen, wo kein http:// davor steht.

angewendet auf einen pfad z.b. ohne http:// wie folgender:

<img src="images/grafik.gif">

kommt das bei heraus (die variable $erweiterung enthält "../de/userpages/.."):

<img src="../de/userpages/./images/banner.gif" alt="" height="115" width="750">

da fehlt zum einen ein punkt vor dem images und zum anderen scheint mit die notation des regex auch nicht wirklich richtig zu sein, so dass es in manchen fällen zu ersetzungen kommt, wo dies eigentlich gar nicht passieren darf.

wenn ich den http zusatz aus dem regex rausnehme funktioniert er wunderbar, ersetzt nur eben auch die absoluten pfade, was nicht sein soll.

kann mir jemand helfen?

  1. Hallo acid_ice,

    [... relative Links aus Dokument filtern ...]

    fuer dein Problem sind die Look-Ahead-Patterns wie geschaffen. Du
    kannst dein Problem so loesen:

    while($doc =~ m~href="(?!http://)([^"]+)"~g) {
      print "URI: $1\n";
    }

    Das setzt aber vorraus, dass alle Links korrekt mit doppelten
    Anfuehrungszeichen umgeben sind. Es bedarf allerdings nur kleiner
    Aenderungen, um das zu korrigieren:

    while($doc =~ m~href=(?:(["'])(?!http://)(.+?)\1))|(?:(?!http://)(\S+))~g) {
      my $uri = $2 || $3;
      print "URI: $uri\n";
    }

    Damit solltest du Links der Art href=../../abc, href="../../abc" und
    href='../../abc' filtern koennen.

    Grüße,
     CK

    --
    Ich bewundere wirklich den Sinn der Bienen für kollektive Verantwortung. Obwohl sich einzelne Bienen hin und wieder bekämpfen, herrscht zwischen Ihnen grundsätzlich ein starkes Gefühl für Eintracht und Zusammenarbeit. Wir Menschen gelten als sehr viel weiter entwickelt, doch mitunter rangieren wir sogar hinter kleinen Insekten.
    http://wwwtech.de/
    1. Hi,
      danke für die Antwort. Es funktioniert tatsächlich - für mein Vorhaben zwar nicht mit einer Schleife, aber es lässt sich einfach über einen erweiterten Ausdruck umsetzen.

      Also - schönen Dank.

      Kannst du mir das jetzt auch erkären, damit ich nicht nochmal fragen muss? ;)

      Und wie siehts aus, wenn ich tatsächlich einmal mit Hilfe von $wert =~ s~asdf~asdfadsf~gi; etwas ersetzen will und im Suchbereich des Musters einen definitiven Ausschluss mit Hilfe von ^ vornehmen will? Also wie wäre da die Notation, wenn ich z.B. http:// aus den Ergebnissen herausfiltern will? [^http] geht ja nicht...

      1. Hallo acid_ice,

        Kannst du mir das jetzt auch erkären, damit ich nicht nochmal
        fragen muss? ;)

        Selbstverstaendlich.

        m~href=(?:(["'])(?!http://)(.+?)\1))|(?:(?!http://)(\S+))~g

        bedeutet ungefaehr:

        »href=« gefolgt von
          entweder
            entweder " oder ' (speichere dies in einer Backreference),
            gefolgt von nicht http:// (allerdings ist dieses Pattern
            ein Zero-Width-Pattern, heisst, der Status bleibt erhalten und
            der Match faehrt nach erfolgreichen »nicht http://« an derselben
            Stelle fort, wo er aufgehoert hat) gefolgt von irgendwas bis zum
            naechsten Zeichen, dass in der Backreference 1 steckt (\1)
            (speichere das irgendwas in einer Backreference)
          oder
            nicht http:// (wieder als Zero-Width-Pattern) gefolgt von alles
            ausser einem Whitespace.

        Die (?:)-Klammern dienen nur der Gruppierung, das ?: verhindert, dass
        diese Klammerung als Backreference gesehen wird.

        Und wie siehts aus, wenn ich tatsächlich einmal mit Hilfe von
        $wert =~ s~asdf~asdfadsf~gi; etwas ersetzen will und im
        Suchbereich des Musters einen definitiven Ausschluss mit Hilfe
        von ^ vornehmen will?

        Eine negierte Klammer (also [^irgendwas]) ist eine negierte
        _Zeichenklasse_, das bedeutet, [^http://] heisst soviel wie »Nicht h
        oder nicht t oder nicht t oder nicht p oder nicht : oder nicht /
        oder nicht /«.

        Also wie wäre da die Notation, wenn ich z.B. http:// aus den
        Ergebnissen herausfiltern will? [^http] geht ja nicht...

        Das haengt davon ab, wie der Ausdruck aussieht. Eine Moeglichkeit
        ist das von mir benannte »zero-width negative look-ahead pattern«.
        Wie gesagt, das haengt davon ab, wie der Ausdruck insgesamt aussehen
        soll.

        Du musst dir klarmachen, dass ein regulaerer Ausdruck einen String
        _beschreibt_. Wenn du also erst darueber nachdenkst, wie der String
        aussehen darf (zuerst ruhig auch mit Worten und schriftlich, spaeter
        mit genuegend Uebung wirst du das nicht mehr brauchen) und danach
        dann das Pattern formulierst, wirst du kaum Probleme haben, den
        richtigen Regex zu finden -- sofern das Problem ueberhaupt durch ein
        Regex geloest werden kann.

        Grüße,
         CK

        --
        <zentrum> wie war noch mal die option in make.conf fuer das benutzen von pipes um das compile zu beschluenigen?
        <CK1> CFLAGS="-pipe"
        <torsten> Oder man frage einen Gentooer seiner Wahl, wie man 2 km Compilerswitches fuer seine CPU hinbekommt ;)
        http://wwwtech.de/