[PHP/RegExp] Der RegExp-Übungsthread

Ui dolle vor den Kopf hau ^^ hast Recht, aber jetzt müsste e ja alles passen oder? Ich nehme mal an ich kann in dem Regex net irgendwie sagen wenn zwischen ><img...</a> dann hole mir den Img alt="". Ich habe es mit "Konditionales Regex" probiert, aber da bekam ich immer einen Fehler rein Kann mir einer von euch den Syntax nochmal erklären??? Er geht ja eigentlich
(?(Bedingungsmuster) Ja-Muster|Nein-Muster)

Also müsste doch folgendes funktionieren:
Code:
(?(^<img.*)<img\s?src="?(?:.*[^"])"?\s?alt="?([^"]*["\s])"?(?:[^>])?>|([^>]*?[^<]))

Dann bekomme ich aber immer einen Fehler im ersten Zeichen also der ( vor dem ?, ichbin in dem Fall echt Ratlos.

Btw. Das Zitat ist von hier, mit dieser Übersicht arbeite ich immer jetzt weis ich allerdings nicht ob bei der mit # markierten Stelle
(?(Bedingungsmuster)#Ja-Muster|Nein-Muster)
ein Freizeichen rein muss, weil ja offensichtlich die Spalte zu klein ist und html bei Freizeichen umbricht, oder ob es beabsichtigt dort umgebrochen ist um dies leserlich zu halten. Wobei dies meiner Meinung nach den fehler nicht erklärt. Vielleicht kennt ja einer von euch ne schönere Übersicht.
 
Ich habe auch noch das Problem das das rotmarkierte verhindert das alles innerhalb title="xxx" nicht gruppiert wird obwohl es vorhanden ist.
Wenn ich jedoch das rote entferne fetscht er nur die links die title="" enthalten die Links die title nicht enhalten werden fallen gelassen.
(?:title="?([^"]*?[^"]))?
Wie kann ich denn anders lösen und dem Ding sagen das gesammte title suchmuster muss nicht vorkommen es kann.

Ich möchte eigentich ein weiteres suchen ohne Titlemuster vermeiden um mich dann nicht mit array_filter rumzuquälen zu müssen. Genauso weinig möchte ich das ich das title Tag in der Gruppierung habe. Hat da auch noch einer von euch ne Idee? Der regex schaut jetzt so aus und funzt soweit ganz gut bis auf das Img Problem im vorherigen Post und dises Title suchmuster.
PHP:
preg_match_all('/<a\s?href="?([^"#][a-zöüä0-9:_~%=&\[\]\?\-\.\+\/]+?[^"#\s])"?\s?title="?([^"][^<>"\']+?[^"])(?:.+)?>([^>]*?[^<])<\/a>/iU', $this->_string['body'], $link, PREG_SET_ORDER)

Mit "Konditionale Regex" wäre ja alles kein Problem aber wenn ich dem das img suchmuster von aoben einbinde mit oder ohne Freizeichen kommt folgender Fehler
Warning: preg_match_all() [function.preg-match-all]: Compilation failed: assertion expected after (?( at offset 102 in /srv/www/web1/html/xxxxxxxxx/xxxx/xxxx/xxxx/class.bot.php on line 60
 
Ich hab übungshalber mal zwei RegExp geschrieben: Einer für das Zerlegen eines INSERT-Statements (Tabellenname, Spaltennamen) und einer für das Zerlegen von UPDATE-Statements (Tabellenname, Spaltennamen).

Hat irgendjemand Verbesserungsvorschläge?

Code:
# INSERT
# Form: INSERT INTO tbl (spalte1,spalte2) ...
/INSERT INTO (\S*) ?\((.*)\) /

Hier bin ich nicht ganz glücklich, das ich es einfach nicht hinbekomme, dass die Formatierungszeichen nicht ins Ergebnis geschoben werden - eigentlich will ich die im Ergebnis gar nicht haben:

Code:
# UPDATE
# Form: UPDATE tbl SET spalte1 = %d, spalte2 = '%s'
/UPDATE (\S*) SET (\S*) ?= ?(%d|'%s'|%s)( ?, ?(\S*) ?= ?(%d|'%s'|%s))*/
(Die ganzen optionalen Leerzeichen kommen nur daher, da ich auch Queries z.B. ohne Leerzeichen nach dem '=' matchen will)
 
Metazeichenbedeutung interpretiert?

Kann mir einer von euch verraten warum der Regex bei einer robots.txt das \n als 'n' sieht
robots.txt
Code:
User-agent: *
Disallow: /images/
Disallow: /error/
Disallow: /codearchiv/
Disallow: /admin/
Disallow: /?site=admin
Disallow: /~logout.
Disallow:/imprint
regex:
PHP:
      preg_match_all("/(?:User-agent:\s?(?:\*|".BOTNAME.")\s)?\nDisallow:\s?([^(?:\nDisallow:\s)].*[^(?:\n|User\-agent:)])/i", $tmp, $this->_robot_txt);
ausgabe:
Array
(
[0] => /images/
[1] => /error/
[2] => /codearchiv/
[3] => /admin/
[4] => /?site=admi
[5] => /~logout.
[6] => /impri
)
der schneidet manchmal bei n ab warum? Bei dem ?site=admin könnte ich es ja noch verstehen wenn ich mich irgendwo vertippt habe, aber bei imprint check ich es absolut nicht. Und ich sitz nu schon 2 Tage dran und komm nicht weiter.
 
Du bist in der Characterklasse drin:
...[^(?:\n|User\-agent:)]...
Da steht: Alles außer den grünen Zeichen.

Wenn du ein "da soll nicht XYZ kommen" haben willst, musst du afaik mit Assertions ran. Das hab ich aber noch nie benutzt.
 
Aber ich habe doch die Assertion außen rum
....[^(?:\n|User\-agent:)]...
oder wie meinst du das? Mal ganz kurz: [abc] trift auf alle möglichen Variationen zu, aber [(abc)] trifft nur auf abc zu, oder war es anders?
 
Zuletzt bearbeitet:
Ok dann schreibe ich es richtig so wie ich es brauche. Ich will sagen wir mal abc und dgh verbieten. Also muss ich [^(abc|dgh)] schreiben. bzw weil ich des eh nicht in einem Subpattern speichern will [^(?:abc|dgh)]. Ist das jetzt so korrekt? Wie gesagt ich will nur das nicht haben. In meinem Konkreten Beispiel wäre das wie oben schon gepostet:
Code:
[^(?:\n|User\-agent:)]
wobei dieses warscheinlich auch ginge
Code:
[^(?:User\-agent:)\n]
Also das Wort 'User-Agent:' und keine Zeilenumbrüche. Wenn ich damit richtig liege warum fetcht mir der regex teilweise die normalen n Buchstaben nicht.
 
Ich will sagen wir mal abc und dgh verbieten. Also muss ich [^(abc|dgh)] schreiben.
Ne, eben nicht. Du kannst in der Characterklasse keine Subpatterns machen, weils da weder ne Klammer, noch n Oder-Zeichen gibt. Der RegExp heißt jetzt:
Alle Zeichen außer (, a, b, c, |, d, g, h und ).

Ich probier das später mal aus, wie man es richtig machen müsste. Aktuell kann ich dir nämlich nur sagen, dass deins falsch is :biggrin:
 
öhm, was willst du denn genau strolch? irgendwie verstehe ich nichtmal den sinn deines falschen ausdrucks mit dem abc defg
 
@theHacker
:mrgreen: danke weil ich bin total ratlos wie man das machen müsste.

@ice-breaker
Ich will eine robots.txt parsen und daher will ich logischerweise nur Dateinamen nach Disallow: und bis zum nächsten Disallow: oder User-Agent: oder zur nächsten Newline. Ich habe einenige Posts zuvor schon alles gepostet ich such es nochmal raus.

*edit
#24 hier

*edit 2
Das wird ne Suchmaschiene ala Shpider oder google, deswegen die ganzen Umstände, aber ich glaube so kann man viel über regex lernen bei sowas Komplexem.
 
würde es nicht einfach reichen folgendes zu machen:
Code:
Disallow: (.*?)
da der punkt nicht den linefeed umfasst hättest du mit preg_match_all alle disallow beindungen und in dem subpattern alles was verboten ist
 
Ich hab jetzt mal probiert, hab aber denselben Weg wie ice-breaker.
Mein Code:
PHP:
<?php

$robots_txt="User-agent: *
Disallow: /images/
Disallow: /error/
Disallow: /codearchiv/
Disallow: /admin/
Disallow: /?site=admin
Disallow: /~logout.
Disallow:/imprint";

define('BOTNAME','foo'); // avoid warning
preg_match_all("/(?:User-agent:\s?(?:\*|".BOTNAME.")\s)?\nDisallow:\s?(.*)/i",$robots_txt,$matches);

header("content-type: text/plain");
print_r($matches);

?>
Ergebnis:
Code:
Array
(
    [0] => Array
        (
            [0] => User-agent: *
Disallow: /images/
            [1] => 
Disallow: /error/
            [2] => 
Disallow: /codearchiv/
            [3] => 
Disallow: /admin/
            [4] => 
Disallow: /?site=admin
            [5] => 
Disallow: /~logout.
            [6] => 
Disallow:/imprint
        )

    [1] => Array
        (
            [0] => /images/
            [1] => /error/
            [2] => /codearchiv/
            [3] => /admin/
            [4] => /?site=admin
            [5] => /~logout.
            [6] => /imprint
        )

)
Falls jetzt jemand 2x Disallow in einer Zeile hat, hat derjenige eh n Syntaxfehler drin und is folglich nicht dein Bier, das dann versuchen, zu lesen.
 
Ahja wieder was gelernt, das mit dem syntax fehler wollte ich halt vermeiden weil ich ja was ordentliches machen will, aber im Grunde hast du recht, ist nicht mein Bier. Gut dann werde ich es so machen, aber nochmal kurz zum mitschreiben das was ich versucht habe ist nicht machbar??? Weil ich noch einen Regex für die Links im Bodytag habe und dort habe ich genauso gearbeitet, weil im HTML halt oft Fehler gemacht werden, welche ich trotzdem so einigermaßen gut behandeln wollte, aber wenn des so net funzt kann ich den Regex ja auch weghaun :-? .

Thx an euch beide.