kostenloser Webspace werbefrei: lima-city


Regex gesucht

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Moin,

    auch ich hab mal ein Problem :wave: Ich suche einen Regex für preg_replace. Ich suche X innerhalb eines Strings, wobei X sich weder in einem HTML-Code (<...>) noch in einem BBCode befinden darf ([...]).

    Jemand eine Idee? Der Regex, mit dem ich matche, scheint nämlich nur maximal bei HTML zu greifen. Wenn überhaupt :slant:

    EDIT:

    Ich suche sogar noch einen:

    [url]http://www.lima-city.de[/url]
    [url='http://www.lima-city.de']Lima-City[/url]
    [url=http://www.lima-city.de]Lima-City[/url]


    Der Regex, den ich suche soll aus allen drei BBCodes jeweils die URL matchen. Ich hatte ja an so etwas gedacht:

    /\[url(\=\'.*\'\]|\=.*\]|\].*)\[\/url\]/i


    Aber das klappt nicht. Zumindest weiß man aber nun, was ich suche :-D Falls man das in dem Chaos nicht auslesen kann: Ich suche nach

    \[url\=\'.*\'\] -- [url='xxxx']
    \[url\=.*\] -- [url=xxxx]
    \[url\].* -- [url]xxx


    Aber jeweils halt NUR die URL.

    Beitrag zuletzt geändert: 17.2.2011 18:21:33 von fabo
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

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

  3. Also mir wäre spontan auch diese Variante Recht:
    /\[url(?:=(?:'([^']+?)'|([^\]]+)))?\]([^\[]*)\[\/url\]/
    da würdest du folgende Ergebnisse bekommen:
    [url]http://www.lima-city.de[/url]:
    $0 = [url]http://www.lima-city.de[/url]
    $1 = 
    $2 = 
    $3 = http://www.lima-city.de
    
    [url='http://www.lima-city.de']Lima-City[/url]:
    $0 = [url='http://www.lima-city.de']Lima-City[/url]
    $1 = http://www.lima-city.de
    $2 = 
    $3 = Lima-City
    
    [url=http://www.lima-city.de]Lima-City[/url]:
    $0 = [url=http://www.lima-city.de]Lima-City[/url]
    $1 = 
    $2 = http://www.lima-city.de
    $3 = Lima-City
    Das hieße also dass man danach mit einer if-Abfrage arbeiten müsste, was preg_match vorraussetzten würde:
    preg_match($regEx, $text, $m);
    $url = ($m[1] ? $m[1] : ($m[2] ? $m[2] : $m[3]));
    str_replace($m[0], "<a href=\"$url\">{$m[3]}</a>", $text)
    Da das aber so nicht gewünscht war würde ich eine preg_replace_callback-Lösung empfehlen:
    preg_replace_callback($regEx, create_function(
        '$m',
        'return "<a href=\"".($m[1] ? $m[1] : ($m[2] ? $m[2] : $m[3]))."\">{$m[3]}<\/a>";'
    ), $text);
    Vielleicht hilft dir die Lösung ja weiter.

    Und auch deine erste Aufstellung würde ich mit einem Callback lösen:
    $regEx = '/([^<\[]*)(<[^>]*>|\[[^\]]*\])/';
    $regExCallback = '/x*/';
    preg_replace_callback($regEx, create_function('$m',
        'return preg_replace("'.$regExCallback.'", "", $m[1]) . $m[2];'
    ), $text)


    Mit freundlichen Grüßen
  4. Zu deinem zweiten Problem:
    '~\[url(?|]([^[]++)|=\'([^\']++)\'][^[]++|=([^]]++)][^[]++)\[/url]~'

    Wenn ich mich nicht vertippt haben sollte, sollte dir das die URL immer in $matches[1] packen.

    Was dein erstes Problem angeht, brauche ich mehr Infos: Können die HTML Tags oder die BB Tags verschachtelt sein? Wenn ja, auch untereinander? Wie valide ist die Eingabe? Sind die HTML Tags XML konform? Sind alle Tags in der richtigen Reihenfolge geschlossen?

    Beitrag zuletzt geändert: 18.2.2011 16:49:46 von nikic
  5. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Hiho,

    danke soweit für die Antworten. Die Lösung von dir, nici, sieht garnicht so uncool aus. Dafür aber das Ergebnis:

    array(1) { [0]=> array(2) { [0]=> string(33) "[url]http://www.lima-city.de[/url]" [1]=> string(22) "http://www.lima-city.de" } }


    Die beiden anderen werden gänzlich ignoriert.

    Zu meinem ersten Problem:

    Es geht einfach darum, innerhalb eines Textes gewisse Ersetzungen durchzuführen. Bei diesen Ersetzungen kann sowohl normales HTML, als auch verschachteltes ingebriffen sein. Ebenso BBCodes.

    Es geht um normale Forenbeiträge d.h. die Ausgabe ist auch Valid und alle Tags sind in der richtigen Reihenfolge geschlossen.

    Ich möchte bei den Ersetzungen einfach vermeiden, dass HTML und BBCode-Tags manipuliert werden sondern lediglich deren Inhalte. Ergo soll der Regex nur matchen, was nicht zwischen < > und [ ] steht, dafür aber davor und danach.

    Ich werde mich mit dem Regex-Gedöns nie anfreunden können.

    Beitrag zuletzt geändert: 18.2.2011 2:05:37 von fabo
  6. @fabo: Ja, habe meinen Regex nun angepasst (und habe das String-Escaping rausgenommen, das ist wahrscheinlich sowieso unerwünscht). Die Ausgabe ist nun:
    array(2) {
      [0]=>
      array(3) {
        [0]=>
        string(34) "[url]http://www.lima-city.de[/url]"
        [1]=>
        string(46) "[url='http://www.lima-city.de']Lima-City[/url]"
        [2]=>
        string(44) "[url=http://www.lima-city.de]Lima-City[/url]"
      }
      [1]=>
      array(3) {
        [0]=>
        string(23) "http://www.lima-city.de"
        [1]=>
        string(23) "http://www.lima-city.de"
        [2]=>
        string(23) "http://www.lima-city.de"
      }
    }


    Zu deinem zweiten Problem: Ah, jetzt verstehe ich. Ich dachte du willst nicht, dass X innerhalb des Tags steht im Sinne von <a>X</a>, nicht im Sinne von <X>.

    Okay, das ist ein nicht mehr ganz einfaches Problem. Ich würde es mit ein wenig schwarzer Magie lösen:
    '~(?:\[/?[^]]++]|</?[^>]++>)(*SKIP)(*FAIL)|X~'


    Beitrag zuletzt geändert: 18.2.2011 16:55:20 von nikic
  7. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Erst einmal danke. Der URL-Regex haut schonmal hin. Jedoch gibt es auch hier noch ein Problem :) Ich muss ja vom worst case ausgehen und da kann es auch sein, dass das rauskommt:

    [url]http://www.lima-city.de[/url]
    [url='http://www.lima-city.de'][b]Lima-City[/b][/url]
    [url=http://www.lima-city.de][i]Lima-City[/i][/url]


    Dann ist die einzige URL, die erkannt wird, die erste. Ich persönlich gestalte meine Links zwar nicht so, aber man kennt ja die User ;) Gibts da auch noch ein Lös'chen für?

    Das Andere werde ich mir jetzt anschauen und mich dann deswegen nochmal melden.

    Aber danke soweit :)

    EDIT:

    Scheint zu funktionieren. Vielen Dank.

    Beitrag zuletzt geändert: 18.2.2011 19:15:25 von fabo
  8. Heh, du forderst aber viel :D Gut, nächster Versuch:
    preg_match_all(
            '~
            (?(DEFINE)
                (?<URLContent>
                    [^[]*+
                    (?:           
                        \[
                        (?!/url])
                        [^[]*+
                    )*+
                )
            )
            \[url
            (?|]([^[]++)
              |=\'([^\']++)\'] (?&URLContent)
              |=([^]]++)]      (?&URLContent)
            )
            \[/url]
            ~x',
            '[url]http://www.lima-city.de[/url]
            [url=\'http://www.lima-city.de\']Lima-City[/url]
            [url=http://www.lima-city.de]Lima-City[/url]
            [url=\'http://www.lima-city.de\'][b]Lima-City[/b][/url]
            [url=http://www.lima-city.de][i]Lima-City[/i][/url]',
            $matches
        );
        echo '<pre>';
        var_dump($matches);


    Achtung: Das gibt dir jetzt die URLs in $matches[2] statt 1. Das (?<URLContent>) ist zwar in nem DEFINE Conditional, aber dennoch ist es ne Capturing Group wie jede andere ;)

    Beitrag zuletzt geändert: 18.2.2011 21:41:46 von nikic
  9. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Mit ein paar weiteren Modifiern scheint es genau so funktionieren, wie ich mir das vorstelle und unter Garantie hätte ich diese Lösung zu Lebzeiten nicht gefunden. Ich danke dir vielmals =)

    Jetzt habe ich aber noch ein, dafür ein (für dich) relativ einfaches Problem...

    Ich habe vor, Domains durch etwas anderes zu ersetzen. Funktioniert mittlerweile u.a. mit deiner Hilfe sehr gut. Nun ist es so, dass ich mit einer Art Blacklist arbeite, deren Einträge nicht ersetzt werden sollen.

    Beispiel (Blacklist):

    http://www.lima-city.de/abc
    http://www.lima-city.de/123


    Beispiel (String)

    http://www.lima-city.de
    http://www.lima-city.de/123
    http://www.lima-city.de/abc


    Momentan passiert (logischerweise) folgendes:

    Ausgabe:

    Ersatzstring
    Ersatzstring/123
    Ersatzstring/abc


    Was ich also benötige ist ein Regex für eine Replace-Anweisung, die ausschließlich http://www.lima-city.de durch Ersatzstring ersetzt, nicht aber http://www.lima-city.de innerhalb der beiden anderen Strings.

    Ich hab mich schon doof gegoogled, um irgendwas zu finden was Replace dazu nötigt, nur das zu ersetzen, was ich suche, nicht aber, was ich nicht ersetzt haben will.

    Die Blacklist ist übrigens ein Array, wogegen der String auch tatsächlich ein String ist.

    EDIT:

    So funktioniert es geringfügig und es zeigt auch gut, was ich eigentlich suche. Aber schön ist das sicherlich nicht ;)

    $text = str_replace($match[2]."[", $ersatzstring."[", $text);


    Ausgehend von den o.g. Varianten des URL-BBCodes funktioniert das aber nicht immer, da nach $match[2] nicht nur [, sondern auch ] und andere Dinge folgen könnten.

    Ich hatte ja gehofft, es würde so gehen, aber ich habs wohl nicht verstanden...

    $text = preg_replace("/".preg_quote($match[2], "/")."$/", $ersatzstring, $text);


    Aber ich hab auch ne gute Nachricht... Sollten wir dieses Problem auch noch in den Griff bekommen, ist mein Projekt fertig und ich werde nicht weiter "fordern" (Ich fordere übrigens nicht, ich bitte nur um Hilfe, weil ich zu blöd bin, diese Probleme selbst zu lösen ^^)

    Beitrag zuletzt geändert: 19.2.2011 5:12:36 von fabo
  10. Ich habe das noch nicht recht verstanden. Möchtest du nur URLs ohne darauf folgenden Pfad ersetzten? Oder willst du wirklich ausnahmslos alle URLs durch einen String ersetzen, außer die URL ist irgendwas bestimmtes? Falls letzteres: Iterier einfach durch die Blacklist durch und seh ob die URL = Blacklist-String ist. Wenn nein, dann ersetze.
  11. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Ich merke, dass meine Probleme und ich langsam nerven :wall: Ich hab nämlich schon wieder eins... Aber alles der Reihe nach :-D

    Zuerst das gegenwärtige Problem:

    Schwierig zu erklären. Vielleicht auch, weil ich langsam übermüdet bin und keine Regexe mehr sehen kann :puke:

    Nehmen wir an, die Blacklist enhält

    http://www.google.de/search?q=test


    Mein String sähe so aus:

    http://www.google.de/search?q=test
    http://www.google.de


    Dann soll http://www.google.de ersetzt werden, nicht aber http://www.google.de/search?q=test - Das ist die Schwierigkeit an dem Ganzen, denn wenn ich es beispielsweise mit einem simplen str_replace mache, wird http://www.google.de in dem String ersetzt, demzufolge auch http://www.google.de/search?q=test. Dies wiederrum darf nicht passieren.

    EDIT:

    Ich glaube langsam, ich denke momentan einfach zu kompliziert. Wenn ich nicht weiter komme, schicke ich dir die Klasse mal per PN, dann kannst du dir ansehen, was genau ich versuche. Danach wirst du dich fragen, wie ich an mein Zertifikat gekommen bin :sex:

    Beitrag zuletzt geändert: 19.2.2011 13:16:35 von fabo
  12. Ah, ich glaube ich habe jetzt verstanden, was du möchtest. Du solltest die URL im Text dann mit Regex ersetzen, mithilfe von
    $text = preg_replace('~' . preg_quote($matches[2], '~') . '(?=\']|]|\[/url])~i', $replacementText, $text)

    Mir fällt jetzt auf Anhieb kein Fall ein, wo das falsche Ergebnisse liefern würde.
  13. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Du hast übrigens 2 Nachrichten ^^ Ich probiers mal aus, danke soweit.

    EDIT:

    YES! Genau so! Perfekt! Ich danke mal wieder vielmals. Das nächste Problem lässt auch nicht lange auf sich warten, aber ich will dir eine kurze Verschnaufpause gönnen =)

    Beitrag zuletzt geändert: 19.2.2011 16:36:09 von fabo
  14. 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!