kostenloser Webspace werbefrei: lima-city


Erneute Suche nach einem Regex

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Guten Morgen,

    wie versprochen, suche ich noch einen Regex für preg_match. Diesmal denke ich jedoch, dass mein Vorhaben nicht all zu kompliziert sein sollte für jene, die sich mit dem Quark auseinandersetzen.

    Es geht um folgenden String:

    Text1;Text2=Text3


    Der Regex sollte nun folgendes Matchen:

    Text1
    Text2
    Text3

    Hierbei ist anzumerken, dass =Text3 nicht zwangsmäßig vorhanden ist. Der String könnte also auch so aussehen:

    Text1;Text2


    Das war's eigentlich =)

    Bisher hatte ich mittels preg_split bzw. explode einfach den String zerschnitten, aber das Ergebnis gefällt mir so absolut nicht. Bemerken sollte ich ggf. noch, dass Text3 lediglich eine URL ist/sein sollte. Wenn Text3 nicht angegeben ist, KANN auch Text2 eine URL sein. Das Ganze filtere ich aber seperat raus. Dazu fehlen mir jedoch momentan halt die Matches =)
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

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

  3. ersetze doch die = durch ; und explode dann auf ;?
    ist vielleicht sogar fixer, als es über preg_match zu lösen.

    Ach btw, du bist nicht der einzige, der Regex als neuen Freund gefunden hat :D

    Beitrag zuletzt geändert: 21.2.2011 11:03:49 von sneppa
  4. ^(.+);(.+)=(.+)$
    Ungetestet, sollte aber hinhauen.

    So aus Interesse: was spricht dagegen, einfach 2 explode()'s zu verwenden? Das wäre bei so einer einfachen Aufgabe unter Umständen sogar schneller.
  5. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Das mit den Explodes klappt nicht ohne Weiteres, weil Text3 wie erwähnt, eine URL sein kann und dann auch dort = exploded wird, wobei ich hier mit Limit arbeiten könnte, was aber auch möglicherweise zu einem falschen Ergebnis führen kann. Aber danke soweit, ich probiers mal aus :)

    EDIT:

    Jetzt weiß ich auch wieder, was das Problem ist/war: Text2 kann auch eine URL sein. Wenn ich den o.g. Regex anwende und Text3 nicht vorhanden ist (aber selbst wenn es vorhanden wäre), wird bei einem möglicherweise in Text2 vorhandenen = gematcht, was wiederrum nicht passieren darf.

    Bin grad erst aufgestanden, dauert etwas, bis das Hirn funktioniert =)

    Hier zwei simple Beispiele:

    Test;Lima-City=http://www.lima-city.de/?rand=12345


    bzw:

    Lima-City=http://www.lima-city.de/?rand=12345


    Gematcht werden sollen:

    Test
    Lima-City
    http://www.lima-city.de/?rand=12345


    bzw:

    Lima-City
    http://www.lima-city.de/?rand=12345


    Beitrag zuletzt geändert: 21.2.2011 16:52:36 von fabo
  6. Das lässt sich trotzdem mit explode() sehr einfach machen:
    <?php
    	$arr = explode(';', $string);
    	$firstPart = $arr['0'];
    	$secondPart = $arr['1']; // wenn du willst, kannst du noch prüfen, ob das überhaupt existiert
    	
    	if (($firstPart != '') && ($secondPart != ''))
    	{
    		$firstPartArr = explode('=', $firstPart, 2);
    		$firstPartOut = $firstPartArr[0];
    		if (isset($firstPartArr[1]))
    		{
    			$firstPartOutUrl = $firstPartArr[1];
    		}
    		
    		$secondPartArr = explode('=', $secondPart, 2);
    		$secondPartOut = $secondPartArr[0];
    		if (isset($secondPartArr[1]))
    		{
    			$secondPartOutUrl = $secondPartArr[1];
    		}
    	} else
    	{
    		// kein match
    	}
    ?>
  7. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Wo wir dann zu dem Ergebnis kämen, dass

    Test;Lima-City=http://www.lima-city.de/?rand=12345


    zwar richtig matcht, jedoch

    Test;http://www.lima-city.de/?rand=12345


    nicht, weil $secondPartArr auf 2 limitiert ist, wogegen es nur auf max. 1, eher 0 limitiert sein dürfte.

    Ich friemel das gleich mal aus, denn einen ähnlichen Ansatz hatte ich ja bereits. Die Ergebnisse waren aber immer gleich bescheiden....

    EDIT:

    Sollte eigentlich so reichen:

    $arr = explode(';', $string);
    	$exp[] = $arr[0];
    	
    	$firstPartArr = explode('=', $arr[1], 2);
    	$exp[] = $firstPartArr[0];
    	if (isset($firstPartArr[1])) {
    		$exp[] = $firstPartArr[1];
    	}


    Liefert aber auch noch das Selbe Ergebnis wie zuvor. Logischerweise ;)

    Beitrag zuletzt geändert: 21.2.2011 17:48:13 von fabo
  8. fabo schrieb:
    Wo wir dann zu dem Ergebnis kämen, dass
    Test;Lima-City=http://www.lima-city.de/?rand=12345
    zwar richtig matcht, jedoch
    Test;http://www.lima-city.de/?rand=12345
    nicht
    Achso, ich dachte, dass die Beschreibung immer vorhanden sein würde und nur die URL weg fallen würde. Dann müsste man prüfen, ob die Beschreibung eine URL (geht auch wieder ohne Regex) ist, wenn nicht, ist sie wirklich eine Beschreibung, wenn doch, ist sie eine URL. Das hast du aber übrigens nicht so beschrieben.
  9. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Bemerken sollte ich ggf. noch, dass Text3 lediglich eine URL ist/sein sollte. Wenn Text3 nicht angegeben ist, KANN auch Text2 eine URL sein.


    Doch, hab ich :-D
  10. fabo schrieb:
    Doch, hab ich :-D
    Hmm, das habe ich wohl nicht so ganz mitbekommen, den ersten Satz in deinem Zitat habe ich aber auf alle Fälle gelesen, sonst hätte ich den Code nicht so geschrieben.

    Auch wenn eine URL ohne Bezeichnung aus meiner Sicht keinen Sinn macht: Schreibe den Code einfach so um, wie ich es dir beschrieben habe, dann dürfte das passen.
  11. Wenn deine "Test2" keine = enthält, dann ginge das:
    (?:([^;]+);)?([^=]+)=(.+)
    Ansonsten wäre das wieder eine Frage für nikic, der hat doch beim letzten mal auch so einen Irren Ausdruck zusammengeschustert.

    Mit freundlichen Grüßen
  12. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Das "wenn" ist das Problem =)
  13. thomasba

    Co-Admin Kostenloser Webspace von thomasba

    thomasba hat kostenlosen Webspace.

    Ich hätte noch diesen hier, setzt allerdings vorraus, das die url immer mit "http" beginnt ;)
    ([^;]+);((http.+)|(.+)=(http.+))


    Wenn nicht, das http einfach mit (http|ftp|bla...) ersetzen ^^
  14. Ok, jetzt ist das Problem ein anderes ;)

    Das geht dennoch ohne komplizierte reguläre Ausdrücke, die man später evtl verändern möchte und nicht kann.

    Ich würde so vorgehen:

    Nach ; exploden
    Nach erstem Vorkommen des = mit strpos() suchen.
    Und dann nach diesem Trennen!

    Ungeprüft:
    $string = "Test;Lima-City=http://www.lima-city.de/?rand=12345";
    
    $teile = explode(";", $string);
    
    foreach ($teile AS $teil)
    {
        $pos = strpos($teil, "=");
        if ($pos > 0)
        {
            echo substr($teil, 0, $pos).'<br>';
            echo substr($teil, $pos+1).'<br>';
        }
        else
        {
            echo $teil.'<br>';
        }
    }


    Ausgabe natürlich nur Beispiel.
    Mit dem Code hättest du auch später noch die Chance weitere Ausnahmen hinzuzufügen.

    Beitrag zuletzt geändert: 22.2.2011 9:38:07 von sneppa
  15. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Wo wir wieder beim Grundproblem wären, dass wenn Text3 nicht existiert, Text2 eine URL mit beinhaltendem Gleichzeichen ein falsches Ergebnis liefert:

    Test
    http://www.lima-city.de/?rand
    12345
  16. Da hast du recht ;)

    $string = "Test;Lima-City=http://www.lima-city.de/?rand=12345";
    
    $teile = explode(";", $string);
    
    foreach ($teile AS $teil)
    {
        $pos = strpos($teil, "=");
        $pos2 = strpos($teil, "?");
        if ($pos > 0 && $pos2 > 0 && $pos2 > $pos)
        {
            echo substr($teil, 0, $pos).'<br>';
            echo substr($teil, $pos+1).'<br>';
        }
        else
        {
            echo $teil.'<br>';
        }
    }

  17. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Nicht schön, aber selten =) Danke, scheint so weit zu funktionieren.
  18. Habs eben getestet, leider war es nicht ganz richtig.

    $string = "Test;d=http://www.lima-city.de/??=rand12345";
    
    $teile = explode(";", $string);
    
    foreach ($teile AS $teil)
    {
        $pos = strpos($teil, "=");
        $pos2 = strpos($teil, "?");
        if ($pos > 0 && ($pos2 == 0 || ($pos2 > 0 && $pos2 > $pos)))
        {
            echo substr($teil, 0, $pos).'<br>';
            echo substr($teil, $pos+1).'<br>';
        }
        else
        {
            echo $teil.'<br>';
        }
    }


    Beitrag zuletzt geändert: 22.2.2011 11:20:29 von sneppa
  19. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Hab ich nicht einmal gemerkt, aber danke :)
  20. So, ich kann leider immer erst später am Abend antworten, aber ich habe mir dein Problem nochmal genauer angesehen und dann folgenden RegEx daraus gebaut:
    (?:([^;]+);)?([^=\?]+\?(?:[^=&]+(?:&|=(?:[^&]+&|[^=]+)))*|[^=]+)(?:=(.+))?
    (hier kannst du den grafisch aufbereitet sehen)
    Der Regex filtert, im Gegensatz zu @drafed-map`s Lösung, alle eindeutigen Möglichkeiten korrekt.
    Nicht eindeutig sind z.B.:
    Test;d?a=http://www.lima-city.de/a=b
    Test;d?a=http://www.lima-city.de/?a=b
    Test;d?a=lima-city.de/a=b
    und ähnliche andere.

    Als Referenzimplentierung habe ich diesen Code auf der Konsole ausgeführt:
    $tests = array(
        "Test;d=http://www.lima-city.de/",
        "Test;d=http://www.lima-city.de/?test=a",
        "Test;d=http://www.lima-city.de?test=a",
        "Test;d=http://www.lima-city.de/?test",
        "Test;d?=http://www.lima-city.de/",
        "Test;d?a=b=http://www.lima-city.de/",
        "Test;d?a=b&c=d=http://www.lima-city.de/",
        "Test;d?a&=http://www.lima-city.de/",
        "Test;d?a=b&=http://www.lima-city.de/",
        "Test;d?a=http://www.lima-city.de/",
        "Test;d?a=http://www.lima-city.de/?a=b",
        "Test;d?a=http://www.lima-city.de/=",
        "Test;d?a=http://www.lima-city.de/",
        "Test;d?a",
        "Test;d?a= =http://www.lima-city.de/", // ...a==http... ergab komische ergebnisse
    );
    
    foreach($tests as $test)
    {
        preg_match("_(?:([^;]+);)?([^=\?]+\?(?:[^=&]+(?:&|=(?:[^&]+&|[^=]+)))*|[^=]+)(?:=(.+))?_", $test, $m);
        print_r($m);
    }


    Beitrag zuletzt geändert: 22.2.2011 23:01:33 von nemoinho
  21. Autor dieses Themas

    fabo

    fabo hat kostenlosen Webspace.

    Hi,

    das sieht schick aus. Auf den ersten Blick entspricht das Ergebnis auch meinen Vorstellungen. Ich werds testen. Danke dafür :)
  22. 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!