kostenloser Webspace werbefrei: lima-city


Hilfe bei Regex

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    benutzernaemelchen

    Kostenloser Webspace von benutzernaemelchen

    benutzernaemelchen hat kostenlosen Webspace.

    Ja, ich schon wieder :>

    Und es geht, wie so oft, um Regex...

    Und zwar suche ich einen Regex, der in Worten so aussieht:

    (KEIN class=) "(.*?)" (KEIN >)

    den mittleren Teil hab' ich schon, klappt perfekt.

    Nur hab ich keinen Plan, wie ich sage, dass ein komplettes Wort NICHT vorkommen darf.

    Ich hab mir jetzt ca. 20 mal sämtliche Regex-Tuts durchgelesen, aber komm eifnach nicht drauf^^

    bei [^abc] bin ich zwar schon angelangt, aber das ist ja auch nicht genau, was ich will :(


    MFG


    Beitrag geändert: 21.9.2008 15:40:26 von benutzernaemelchen
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Ich habe auch nur eine ungefähre Lösung gefunden - vielleicht findet ja jemand "die ganze Wahrheit" ...

    In Perl gibt es (negative) Lookaheads, ?= / ?!.
    Konkret würde ich etwas in der Art
    (?!class=)"(.+?)"(?!>)

    vorschlagen.
    Erklärung:
    (?=x) sucht nach x, gibt es aber nicht als Ergebnis zurück. Es testet also nur, ob es da ist, ohne es zum Fund-Ergebnis hinzuzufügen.
    (?!x) als "Negation" prüft, ob x nicht vorkommt.
    In beiden Fällen zählt () übrigens ausnahmsweise nicht als Fundstelle - das Ergebnis liegt also in $2, nicht in $1.

    Leider funktioniert mein Vorschlag nicht ganz:
    in                           wird gefunden
    --------------------------   ------------------
    blub="wanted" blob         wanted
    class="half-wanted" blob   half-wanted - ob Du das willst, ist mir unklar
    ok="half-wanted2">         (nichts)
    class="unwanted">          (nichts) - richtig

    (Bitte die Backslashes vor den Anführungszeichen ignorieren - die hat die Foren-Software hinzu-erfunden)
    Die beiden halb-und-halb-Fälle in der Mitte ... nun, ich hätte erwartet, daß auch das zweite Beispiel nicht gefunden wird, weil ja class= vor dem Anführungszeichen steht. Obendrein befürchte ich, daß mindestens eines Deiner Absicht widerspricht.

    hth
  4. Autor dieses Themas

    benutzernaemelchen

    Kostenloser Webspace von benutzernaemelchen

    benutzernaemelchen hat kostenlosen Webspace.

    hm, geht hier irgendwie nicht(frag mich nicht, wieso^^).

    Nochmal ne kleine Erklärung:

    ich habe Strings, z.B.

    "aaa<span class="xyz">blubb</span> wuhu!"

    Jetzt will ich eben nicht nur
    aaa<span class=
    haben, was ich kriegen würde, wenn ich nur nach "(.*?)" suchen würde, sondern eben den gesamten.

    Es gibt also 3 arten von "-Vorkommnissen:
    als class: class=" (will ich nicht)
    ende des span-tags: "> (will ich nicht)
    und das "normale": "text"

    Mein text darf also weder mit class= anfangen, noch mit einem > enden.

    Hat mir eigentlich mal jemand nen Link zu irgendnem regex-prog, bei dem ich den regex und den zu bearbeitenden Text eingeben kann, damit ich das mal ein bisschen besser analysieren kann?



    MfG

  5. "aaa<span class="xyz">blubb</span> wuhu!"

    Jetzt will ich eben nicht nur
    aaa<span class=
    haben, was ich kriegen würde, wenn ich nur nach "(.*?)" suchen würde, sondern eben den gesamten.


    Sorry, das habe ich nicht verstanden: Was würdest Du in diesem Fall als Ergebnis haben wollen: "aaa", "blubb" oder "aaablubb wuhu!" ?

    Grundsätzlich sind reguläre Ausdrücke für Parsing nur begrenzt geeignet - spätestens, wenn Klammern (im weitesten Sinne, also auch: öffnende / schließende Tags), Quoting oder Escape-Zeichen eine Rolle spielen, ist es extrem schwierig bis unmöglich, damit zum Ziel zu kommen - es sei denn, man weiß aus bestimmten Gründen, daß nur ein paar wenige Kombinationen (die man dann explizit berücksichtigt) auftreten können.
  6. Welchen Teil deines Strings

    "aaa<span class="xyz">blubb</span> wuhu!"

    willst du denn haben? Denn danach richtet sich ja der RegEx.
    Ansonsten hat dis-order schon Recht, auch in PHP gibt es diese Konstrukte, ich verlinke mal hierauf http://de.php.net/manual/en/regexp.reference.php Abschnitt "Assertions".

  7. Hat mir eigentlich mal jemand nen Link zu irgendnem regex-prog, bei dem ich den regex und den zu bearbeitenden Text eingeben kann, damit ich das mal ein bisschen besser analysieren kann?

    http://gskinner.com/RegExr/ macht genau das ;)

    Ryan
  8. Autor dieses Themas

    benutzernaemelchen

    Kostenloser Webspace von benutzernaemelchen

    benutzernaemelchen hat kostenlosen Webspace.


    Welchen Teil deines Strings

    "aaa<span class="xyz">blubb</span> wuhu!"

    willst du denn haben? Denn danach richtet sich ja der RegEx.
    Ansonsten hat dis-order schon Recht, auch in PHP gibt es diese Konstrukte, ich verlinke mal hierauf http://de.php.net/manual/en/regexp.reference.php Abschnitt "Assertions".

    ich will den gesamten, also
    aaa<span class="xyz">blubb</span> wuhu!
    .
    Wenn ich aber nur /\\"(.*?)\\"/ hätte, würde ich ja nur ein
    aaa<span class=
    kriegen, weil dann schon das nächste " folgt.





  9. Ok, ich verstehe dein Problem, aber eine Lösung will mir auf die Schnelle nicht einfallen. Das Problem ist eher, den Abschnitt vor <span... zu bekommen. Du könntest drei einzelne RegEx basteln und die dann wieder zusammensetzen, dass du deinen gesuchten Abschnitt hast. Das sollte ohne Probleme zu machen sein. Vielleicht kann man auf dieser Basis dann wiederum alle drei vereinen und einen einzigen Ausdruck erstellen.
    RegEx sind leider immer ein bisschen try and error...


    Beitrag geändert: 21.9.2008 21:42:23 von tct

  10. ich will den gesamten, also
    aaa<span class="xyz">blubb</span> wuhu!

    Wenn ich aber nur /"(.*?)"/ hätte, würde ich ja nur ein
    aaa<span class=
    kriegen, weil dann schon das nächste " folgt.


    Jetzt bin ich total verwirrt - mit /"(.*?)"/ (wozu da die Backslashes sein sollten, verstehe ich schon nicht) würdest Du doch allenfalls das "xyz" (ohne die Anführungszeichen drumherum) bekommen. Auch den Teil ".*?" verstehe ich nicht - wo ist da der Unterschied zu ".*" ?

    Wie auch immer: Habe ich es richtig verstanden: Du willst aus einer Zeile HTML etwas herausschneiden, wo erst Text, dann ein Span mit einer bestimmten (?) Klasse und dann wieder Text steht ? Mal abgesehen davon, daß mir Anfang und Ende dessen, was du finden willst, unklar sind (oder willst Du vielleicht nur testen ?), sollte dazu doch genügen:
    /(.+<span class="xyz">.+</class>.+)/

    (Die runden Klammern brauchst Du nur, wenn Du das gefundene auch zurückbekommen willst)

    Ich habe wenig Hoffnung, daß das jetzt die Lösung Deines Problems ist (übrigens habe ich's auch nicht getestet, eigentlich ein Kardinalfehler bei RegExp...); schreib' einfach nochmal, was daran falsch ist.


    Beitrag geändert: 21.9.2008 21:48:58 von dis-order
  11. Autor dieses Themas

    benutzernaemelchen

    Kostenloser Webspace von benutzernaemelchen

    benutzernaemelchen hat kostenlosen Webspace.



    ich will den gesamten, also
    aaa<span class="xyz">blubb</span> wuhu!

    Wenn ich aber nur /"(.*?)"/ hätte, würde ich ja nur ein
    aaa<span class=
    kriegen, weil dann schon das nächste " folgt.


    Jetzt bin ich total verwirrt - mit /"(.*?)"/ (wozu da die Backslashes sein sollten, verstehe ich schon nicht) würdest Du doch allenfalls das "xyz" (ohne die Anführungszeichen drumherum) bekommen.

    Nein.
    Der String sieht so aus: (Die " am Anfang und am Ende gehören dazu):
    "aaa<span class="xyz">blubb</span> wuhu!".

    Auch den Teil ".*?" verstehe ich nicht - wo ist da der Unterschied zu ".*"

    Ist doch Wurscht :P


    das Problem sind eigentlich nur die Anführungszeichen. Ich will ALLES zwischen dem Anfangs- und End " haben.
    Wenn ich aber nur alles zwischen den " rausfiltere, bekomme ich eben ein
    aaa<span class=
    raus. Ist ja auch klar.

    Die Unterschiede zwischen den einzelnen Vorkommnissen eines Anführungszeichen sind also einfach, dass bei einem span-Tag, den ich ja nicht beachten will, bei den Anführungszeichen IMMER ein class= davor steht, ODER ein > dahinter ist.

    Wenn ich also alles zwischen 2 Anführungszeichen nehme, die weder ein class= davor haben, noch ein > dahinter, sollte es das eigentlich gewesen sein.

    Ich weiß zwar nicht, wie ich das machen soll, aber hoff einfach mal, dass mein Problem jetzt endlich verständlich ist.
  12. Wenn die " am Anfnag und Ende zum Ausdruck gehören sollen, dann ist das doch gar kein Problem. Ist zwar nicht getestet, aber könnte so gehen:

    '~\"(.*)<span class=\"(.*)\">(.*)<\/span>(.*)\"~Usim'


    (wobei ich die " und das / mit Backslashes escaped habe, aber die verschluckt das Forum)
  13. Ich will ALLES zwischen dem Anfangs- und End " haben.
    Wenn ich aber nur alles zwischen den " rausfiltere, bekomme ich eben ein
    aaa<span class=
    raus. Ist ja auch klar.

    Ähem - nö!
    Reguläre Ausdrücke sollten normalerweise "gierig" sein, d.h., sie suchen die längst-mögliche Zeichenkette, die paßt (das kann man aber oft abstellen). Gerade deshalb hat man oft Streß: Wenn ich z.B. nach Anfangs- und End-" in
    Ob "a" oder "b" interessiert niemanden

    suche, bekomme ich 'a" oder "b' zurück - obwohl man die zwei (!) Funde 'a' und 'b' erwartet. Auch bei Deinem Beispiel hat's bei mir funktioniert.

    Zurück zu Deinem Problem: tct dürfte da schon ziemlich richtig liegen. Da wird eben etwas geprüft, ob die Struktur stimmt - das ist sicher nicht überflüssig. Wenn Du um alles außer den " noch zusätzlich runde Klammern machst, bekommst Du den ganzen Krimskrams (in Perl) als $1.
    Ich bin selbst auf eine etwas andere Lösung gekommen:
    (.+<span class="xyz">.+</span>.+)

    (vor dem / im schließenden Tag hat das Forum ein Backslash verschluckt)


    Beitrag geändert: 21.9.2008 22:43:56 von dis-order


    Beitrag geändert: 21.9.2008 22:45:52 von dis-order

  14. Auch den Teil ".*?" verstehe ich nicht - wo ist da der Unterschied zu ".*" ?

    Der ohne Fragezeichen ist gierig und der andere eben nicht ^^

    In diesem Fall brauchst du eine gieriege, da der Regex bei `class="` nicht stoppen soll. Also `.*` und nicht `.*?`

    \\"(.*)\\"

    oder wenn die Gänsefüschen in einer extra Zeile stehen geht sogar das hier:

    ^\\"(.*)\\"$

    Ryan


    Beitrag geändert: 22.9.2008 9:38:24 von ryanblack
  15. Autor dieses Themas

    benutzernaemelchen

    Kostenloser Webspace von benutzernaemelchen

    benutzernaemelchen hat kostenlosen Webspace.

    Dass ich einfach nen gierigen nehm funktioniert wahrscheinlich genausowenig.
    Nochmal konkret:
    ein
    "aaa<span class="xyz">blubb</span> wuhu!".
    Ist ja nicht alles, was ich hab.
    ich habe z.B. sowas:(Ich schreib am Anfang absichtlich KEINE ")


    blubb1 blubb2 "tralala!" <span class="class1">tüddeldü!</span> "wuhu<span class="class2">muh!</span>"

    wenn ich jetzt nach allen " gierig suchen lasse, bekomm' ich doch:

    tralala!" <span class="class1">tüddeldü!</span> "wuhu<span class="class2">muh!</span>

    Und das will ich eben nicht :)

    was ich will ist in dem Fall einmal
    tralala!
    und
    wuhu<span class="class2">muh!</span>

    deshalb muss ich nach den " suchen, die weder ein class= davor haben, noch ein > dahinter.
    Wenn ich das mach, würde ich genau meine gesuchten Ergebnisse kriegen.

    (Das restliche gepostete klappt nicht - und ich glaub einfach mal, dass der falsche Ansatz verwendet wurde *g*)
  16. ...
    blubb1 blubb2 "tralala!" <span class="class1">tüddeldü!</span> "wuhu<span class="class2">muh!</span>"

    wenn ich jetzt nach allen " gierig suchen lasse, bekomm' ich doch:

    tralala!" <span class="class1">tüddeldü!</span> "wuhu<span class="class2">muh!</span>

    Und das will ich eben nicht :)

    was ich will ist in dem Fall einmal
    tralala!
    und
    wuhu<span class="class2">muh!</span>

    deshalb muss ich nach den " suchen, die weder ein class= davor haben,

    negative Lookbehind-Assertion

    noch ein > dahinter.

    negative Lookahead-Assertion


    Wenn ich das mach, würde ich genau meine gesuchten Ergebnisse kriegen.

    (Das restliche gepostete klappt nicht - und ich glaub einfach mal, dass der falsche Ansatz verwendet wurde *g*)

    Das liegt daran, dass mit Regulären Ausdrücken (fast) nur "nach etwas" gesucht werden kann und nicht "nicht nach etwas". Und dann lernen wir alle im Laufe der Zeit dazu. Komplexe Assertions sind eben eine Ebene höher angesiedelt. Nach deiner Problembeschreibung gebastelt, ergäbe das folgenden RegEx:

    /(?<!class=)"(?!>)/
    [1]

    http://de.php.net/manual/de/regexp.reference.php#regexp.reference.assertions


    --
    [1]und das selbstverständlich ohne den dämlichen Smiley (am besten schaust du im Quelltext nach ...).





    Beitrag geändert: 22.9.2008 19:35:41 von alopex
  17. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!