henman: switch mit preg_match

hallo alle,

in einem switch habe ich als case zweimal preg_match verwendet.

$var1 = 'checkbox(firma_messegrund5)input';  
$var2 = 'radio(firma_messegrund5)input';  
  
switch($var2)  
{  
case preg_match('/checkbox\((.*)\)input/',$var2):  
	echo'Checkbox gefunden';break;  
  
case preg_match('/radio\((.*)\)input/',$var2):  
	echo'Radio gefunden';break;  
default:break;  
}

Ergebnis: Checkbox gefunden
?? Warum matcht er genau das Falsche? ich habe dann mal $var1 in den switch genommen (auch in preg_match() geändert) und er findet wieder das falsche.
Auch als ich nur nach /checkboxinput/ in 'checkboxinput' gesucht hab, nimmt er das falsche.

benutze ich eine if-Abfrage, geht es. Kann es sein, dass switch reguläre Ausdrücke nicht wirklich mag?

mir wirds schon zu bunt, ich benutz dann doch lieber if(), trotzdem würd ich gern wissen, warum das so ist.

grüße,
henman

--
"Sir! We are surrounded!" - "Excellent! We can attack in any direction!"
sh:( fo:| ch:? rl:° br:> n4:? ie:% mo:) va:| de:] zu:) fl:{ ss:| ls:[ js:|
  1. Hi,

    switch($var2)
    {

    Versuch mal switch(true)

    Schöne Grüße

  2. Hi henman!

    Dein Code ist völlig vermurkst. So wäre es wohl in deinem Sinne:

    $var1 = 'checkbox(firma_messegrund5)input';  
    $var2 = 'radio(firma_messegrund5)input';  
      
    switch(true)  
    {  
      case preg_match('/checkbox\((.*)\)input/',$var2):  
        echo'Checkbox gefunden';  
      break;  
      
      case preg_match('/radio\((.*)\)input/',$var2):  
        echo'Radio gefunden';  
      break;  
    }
    

    Ergebnis: Checkbox gefunden
    ?? Warum matcht er genau das Falsche? ich habe dann mal $var1 in den switch genommen (auch in preg_match() geändert) und er findet wieder das falsche.

    Du hättest in den Switch-Kopf jeden beliebigen String stecken können und wärst immer wieder zum gleichen Ergebnis gekommen. preg_match('/checkbox\((.*)\)input/',$var2) gibt 0 zurück. Der Vergleich von 0 mit $var2 ergibt true. Also wird "Checkbox gefunden" ausgegeben und anschließen mit break das Switch-Statement verlassen.

    Vielleicht solltest du dir nochmal die Wirkungsweise von switch anschauen.

    MfG H☼psel

    --
    "It's amazing I won. I was running against peace, prosperity, and incumbency."
    George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
    Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
    1. hallo Hopsel,

      Du hättest in den Switch-Kopf jeden beliebigen String stecken können und wärst immer wieder zum gleichen Ergebnis gekommen. preg_match('/checkbox\((.*)\)input/',$var2) gibt 0 zurück. Der Vergleich von 0 mit $var2 ergibt true. Also wird "Checkbox gefunden" ausgegeben und anschließen mit break das Switch-Statement verlassen.

      Vielleicht solltest du dir nochmal die Wirkungsweise von switch anschauen.

      mwha! ja, dankeschön! Blöder Fehler ;P

      grüße,
      henman

      --
      "Sir! We are surrounded!" - "Excellent! We can attack in any direction!"
      sh:( fo:| ch:? rl:° br:> n4:? ie:% mo:) va:| de:] zu:) fl:{ ss:| ls:[ js:|
  3. Hallo,

    in einem switch habe ich als case zweimal preg_match verwendet.

    ja, und du hast damit erstens ein Verständnisproblem, zweitens ein Problem mit der automatischen Typumwandlung.

    $var2 = 'radio(firma_messegrund5)input';

    switch($var2)
    {

    Hier willst du also abhängig vom Wert von $var2 eine Fallunterscheidung treffen.

    case preg_match('/checkbox((.*))input/',$var2):

    Die folgenden Anweisungen werden ausgeführt, wenn $var2==preg_match(...) ist. Nun ist $var2 ein String, preg_match liefert jedoch eine Zahl zurück. Zunächst wird also $var2 auch in einen Zahlenwert umgewandelt - und zwar, weil der Stringwert nicht sinnvoll als Zahl interpretierbar ist, in den Wert 0. Auf der anderen Seite des Vergleichsoperators hat preg_match() den gesuchten Ausdruck 1mal gefunden, im Endeffekt ermittelt das case-Statement also 0==1, und das ergibt false. Der Folgeblock wird also nicht ausgeführt.

    case preg_match('/radio((.*))input/',$var2):

    In diesem Fall liefert preg_match() eine 0, weil der Suchausdruck nicht gefunden wurde. Das case-Statement vergleicht also 0==0, und das ergibt true, also wird der nachfolgende Block ausgeführt.

    benutze ich eine if-Abfrage, geht es. Kann es sein, dass switch reguläre Ausdrücke nicht wirklich mag?

    Nein, das hat damit nichts zu tun. Es hat damit zu tun, dass dir die Arbeitsweise von switch/case nicht wirklich klar ist: Der Ausdruck in switch() wird nacheinander mit allen case-Ausdrücken vergleichen, bis eine Übereinstimmung gefunden wird.

    mir wirds schon zu bunt, ich benutz dann doch lieber if(), trotzdem würd ich gern wissen, warum das so ist.

    Nach deiner Denkweise bräuchtest du eine Funktion, die nicht eine ja/nein-Aussage liefert, sondern den gefundenen Ausdruck selbst. Dann könntest du mit deinem switch-Konstrukt weiterkommen.

    So long,
     Martin

    --
    F: Was sagt die kleine Kerze zur großen Kerze?
    A: Ich gehe heute nacht aus!
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    1. Hi!

      Liebe Mitleser, bitte erst die Richtigkeit kontrollieren, dann "fachlich hilfreich" kennzeichnen. In diesem Fall ist das nämlich nicht ganz gerechtfertigt, denn Der Martin hat sich geirrt. Er hat seine Betrachtung mit dem Inhalt von $var1 gemacht und kommt damit auf falsche Ergebnisse. Seine Schlussfolgerung ist auch nicht ganz richtig, denn mit 1 (nicht true!) im switch-Ausdruck kommt man zum Ziel, denn preg_match liefert in genau einem Fall als Anzahl der Fundstellen eine 1. (Das heißt, mit true kommt man auch zum Ziel, aber nur, weil PHP noch eine Typkonvertierung von true zu 1 vornimmt (oder auch umgekehrt), die aber nicht notwendig ist, wenn man gleich die Zahlenwerte vergleicht.)

      Lo!

      1. Hallo,

        Liebe Mitleser, bitte erst die Richtigkeit kontrollieren, dann "fachlich hilfreich" kennzeichnen.

        ich habe mich schon über einen neuen Fan gefreut. ;-)

        In diesem Fall ist das nämlich nicht ganz gerechtfertigt, denn Der Martin hat sich geirrt. Er hat seine Betrachtung mit dem Inhalt von $var1 gemacht und kommt damit auf falsche Ergebnisse.

        Stimmt, ich habe mich tatsächlich geirrt. Ich habe Codeausschnitt und Erklärung verkehrt zugeordnet. Die eigentliche Aussage bzw. die Erklärung ist aber in der Sache richtig, behaupte ich mal.

        Seine Schlussfolgerung ist auch nicht ganz richtig, denn mit 1 (nicht true!) im switch-Ausdruck kommt man zum Ziel, denn preg_match liefert in genau einem Fall als Anzahl der Fundstellen eine 1.

        Das fiel mir hinterher auch wieder auf, als ich die anderen Beiträge las, die in der Zwischenzeit eingetroffen waren. Allerdings ist mir diese Verwendung von switch/case immer etwas suspekt. Ich weiß, dass der case-Ausdruck in PHP (auch Javascript) tatsächlich ein Ausdruck sein kann, bin aber von anderen Sprachen wie etwa C/C++ gewöhnt, dass dort nur eine Konstante stehen darf. Entsprechend komme ich meist nicht auf den Gedanken, eine Konstante bei switch() zu notieren.

        (Das heißt, mit true kommt man auch zum Ziel, aber nur, weil PHP noch eine Typkonvertierung von true zu 1 vornimmt (oder auch umgekehrt), die aber nicht notwendig ist, wenn man gleich die Zahlenwerte vergleicht.)

        Richtig. Wobei ich noch nie verstanden habe, warum man extra einen Boolean-Typ definiert, obwohl der keine andere Aussage transportiert als die andernorts ersatzweise verwendeten numerischen Konstanten 0 oder 1 (oder allgemein 0 und !=0). Gut, in PHP hat man daraus insofern eine Tugend gemacht, als Funktionen einen numerischen Wert _oder_ false zurückgeben können, und das sogar unterscheidbar ist.

        So long,
         Martin

        --
        Chef zum Bewerber: Es gibt zwei Dinge, auf die ich allergrößten Wert lege. Das eine ist Sauberkeit! Haben Sie übrigens die Schuhe auf der Matte abgetreten? - Ja, selbstverständlich. - Gut. Das andere ist uneingeschränkte Ehrlichkeit. Übrigens, draußen liegt gar keine Fußmatte.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. Hi!

          Stimmt, ich habe mich tatsächlich geirrt. Ich habe Codeausschnitt und Erklärung verkehrt zugeordnet. Die eigentliche Aussage bzw. die Erklärung ist aber in der Sache richtig, behaupte ich mal.

          Ja.

          Wobei ich noch nie verstanden habe, warum man extra einen Boolean-Typ definiert, obwohl der keine andere Aussage transportiert als die andernorts ersatzweise verwendeten numerischen Konstanten 0 oder 1 (oder allgemein 0 und !=0).

          Doch, wenn man typsicher arbeitet, will man den Unterschied genauso haben wie den zwischen NULL und 0.

          Gut, in PHP hat man daraus insofern eine Tugend gemacht, als Funktionen einen numerischen Wert _oder_ false zurückgeben können, und das sogar unterscheidbar ist.

          Eben. Siehe strpos(): "gefunden an Position 0" ist was anderes als "nicht gefunden" (false). Wenn du diese beiden Fälle auseinanderhalten willst, brauchst du ohne Boolean einen weiteren Zahlenwert, wie -1. Auf den müsste man dann wieder extra vergleichen. Dumm nur, dass man wegen PHPs automatischer Typumwandlung und dem nicht typsicherem Auswerten des if-Arguments explizit typsicher auf false vergleichen muss.

          Allerdings hat man in Sprachen mit starker Typisierung nicht die Möglichkeit, Boolean und Integer gemixt zurückgeben zu können. Trotzdem sehe ich da die Existenz von Boolean nicht als überflüssig an. Wenn (wie in C#) definiert ist, dass if nur boolesche Werte auswerten darf, kann man nicht aus Versehen einen Ausdruck notieren, der Integer zum Ergebnis hat. Da hat schon der Compiler was dagegen. Hier muss man typsauber vergleichen oder explizit typecasten, was auch dem Code-Leser beim verstehen der Intention hilft. C dürfte da nachlässiger sein und maximal eine Warnung werfen.

          Lo!

          1. Hallo,

            Allerdings hat man in Sprachen mit starker Typisierung nicht die Möglichkeit, Boolean und Integer gemixt zurückgeben zu können. Trotzdem sehe ich da die Existenz von Boolean nicht als überflüssig an. Wenn (wie in C#) definiert ist, dass if nur boolesche Werte auswerten darf, kann man nicht aus Versehen einen Ausdruck notieren, der Integer zum Ergebnis hat.

            das würde ich aber wieder als unbequeme Einschränkung sehen, da ich seit gut zwanzig Jahren in verschiedenen Programmiersprachen (schwerpunktmäßig aber C) ausnutze, dass alles, was numerisch nicht null oder nicht der NULL-Pointer ist, im boolschen Kontext als true gilt. Die strenge Unterscheidung ist etwas, was mich zum Beispiel in Pascal immer sehr gestört hat.

            Da hat schon der Compiler was dagegen. Hier muss man typsauber vergleichen oder explizit typecasten, was auch dem Code-Leser beim verstehen der Intention hilft.

            Ich bin da schon so verkorkst, dass es mir nicht hilft - im Gegenteil, durch explizit ausformulierte Typecasts wird der Ausdruck oft unübersichtlich und IMHO schwerer zu durchschauen. Anstatt

            char *buffer;  
            if ((buffer=(char *)malloc(BUFFERSIZE))!=NULL)
            

            notiere ich ohne expliziten Typecast und ohne expliziten Vergleich einfach

            char *buffer;  
            if (buffer=malloc(BUFFERSIZE))
            

            und finde das wesentlich übersichtlicher und leicher, schneller nachvollziehbar. Natürlich ist das eine Gewöhnungssache.

            C dürfte da nachlässiger sein und maximal eine Warnung werfen.

            Nicht mal das. C akzeptiert das einfach, fertig.

            So long,
             Martin

            --
            "Wie geht eigentlich dein neues Auto?"
            "Es geht nicht, es fährt!"
            "Äh, ja. Und wie fährt es?"
            "Och, es geht."
            Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
  4. Hi!

    Kann es sein, dass switch reguläre Ausdrücke nicht wirklich mag?

    Nein, was du da als Ausdruck notierst ist dem switch egal, denn es bekommt nur dessen Ergebnis zu Gesicht. Das Ergebnis der Ausdrucks

    preg_match('/checkbox((.*))input/',$var2)

    ist 0. Wenn man $var2 mit 0 vergleicht, wird Der Inhalt von $var2 in einen Integer konvertiert, dabei kommt 0 raus. 0 == 0, erster case passt.

    Du möchtest nicht $var2 (konvertiert zu 0) mit den Ergebnissen der preg_matches vergleichen sondern das Ergebnis, das preg_match im Erfolgsfall liefert, soll mit dem switch-Ausdruck übereinstimmen.

    Lo!

    1. hallo dedlfix,

      Du möchtest nicht $var2 (konvertiert zu 0) mit den Ergebnissen der preg_matches vergleichen sondern das Ergebnis, das preg_match im Erfolgsfall liefert, soll mit dem switch-Ausdruck übereinstimmen.

      joar, dann hat sich das eh erledigt mit switch, da der switch auch
      case 'foo': tuwas(); beinhaltete.
      Da Strings typstark auch True sind, würde er alles liefern. Selbst wenn nicht, dann wüsste switch ja nicht, womit es 'foo' vergleichen sollte.

      grüße,
      henman

      --
      "Sir! We are surrounded!" - "Excellent! We can attack in any direction!"
      sh:( fo:| ch:? rl:° br:> n4:? ie:% mo:) va:| de:] zu:) fl:{ ss:| ls:[ js:|
      1. Hi!

        Du möchtest nicht $var2 (konvertiert zu 0) mit den Ergebnissen der preg_matches vergleichen sondern das Ergebnis, das preg_match im Erfolgsfall liefert, soll mit dem switch-Ausdruck übereinstimmen.
        joar, dann hat sich das eh erledigt mit switch, da der switch auch
        case 'foo': tuwas(); beinhaltete.

        Du kannst trotzdem switch verwenden, wenn es dich nicht stört, dass du grad die übliche Notationsweise umgedreht hast. Normalerweise nimmt man ja

        switch (variable/ausdruck)
            case konstanter_wert_1:
            case konstanter_wert_2:

        PHP erlaubt auch den umgedrehten Weg, der aber weniger üblich ist, weil er auch nicht in allen Systemen, die switch kennen, so funktioniert.

        switch (konstanter_wert)
            case variable_1/ausdruck_1:
            case variable_2/ausdruck_2:

        Das ergibt dann bei dir sinngemäß:

        switch (1)
            case preg_match(checkbox, $var):
            case preg_match(radio, $var):
            case 'foo' == $var:

        Im dritten Fall liefert der Vergleich true = 1 oder false = 0 und passt oder nicht. An dieser Stelle muss man sich dann doch in der einen Sorte der Ausdrücke der Typkonvertierung zwischen Integer und Boolean bedienen.

        Da Strings typstark auch True sind, würde er alles liefern.

        Typstark (eigentlich typsicher) bedeutet, dass der Typ berücksichtigt wird und damit 'foo' !== true ist. switch arbeitet aber nicht mit typsicher.

        Selbst wenn nicht, dann wüsste switch ja nicht, womit es 'foo' vergleichen sollte.

        Na doch, es ist ja definiert, dass switch seinen Klammerausdruck mit den Ergebnissen der case-Ausdrücke vergleicht. Das Problem ist nicht das switch, sondern es so anzuwenden, dass es das gewünschte Ergebnis liefert. (Bei dieser Lösung wird es auf ungewöhnliche Weise verwendet, was man zurecht bedenklich finden kann, weil es wegen seiner Ungewöhnlichkeit schwerer verständlich ist.)

        Lo!