Tom: preg_match

Hello,

ich knabber immer noch an der Zerlegung der Table-Metadaten:

Typenliste (1)

Typen sind zur Zeit:

#   tinyint
#   smallint
#   mediumint
#   int
#   bigint
#   float
#   double
#   decimal
#   date
#   datetime
#   timestamp
#   time
#   year
#   char
#   varchar
#   tinyblob
#   tinytext
#   text
#   blob
#   mediumblob
#   mediumtext
#   longblob
#   longtext
#   enum
#   set

So können die Typen auch auftreten

Formatbeispiele:

#   bigint(20) unsigned
#   timestamp(14)
#   varchar(30)
#   set('EINS','ZWEI','DREI','VIER','FÜNF')
#   float(11,10)
#   double(11,5)
#   decimal(10,2)
#   year(2)
#   char(2)
#   enum('eins','zwei','sieben','12')

Ich muss als Zerlegungsergebnis nun haben:

1. Typschlüsselwort laut obiger Liste
2. Wenn (a[,b][,c][, ]) vorhandene Liste "a,b,c" mit oder ohne '
3. ob "unsigned" vorhanden entweder true/false oder das Wort

Irgendwie bekomme ich aber nicht hin und brauche Eure Hilfe

Liebe Grüße aus http://www.braunschweig.de

Tom

--
Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
  1. Hello,

    Hello,

    So können die Typen auch auftreten

    Formatbeispiele:

    #   bigint(20) unsigned
    #   timestamp(14)
    #   varchar(30)
    #   set('EINS','ZWEI','DREI','VIER','FÜNF')
    #   float(11,10)
    #   double(11,5)
    #   decimal(10,2)
    #   year(2)
    #   char(2)
    #   enum('eins','zwei','sieben','12')

    Ich habe jetzt:

    $type="([a-z]{3,})";
    #$len="([0-9]{1,3})";  # funktioniert noch nicht
    #$dec=",([0-9]{1,3})"; # funktioniert noch nicht

    preg_match("#^$type{1}((([^)]+)))*(\s(unsigned){1})*#i",
       $metasum, $matches);

    $matches[1],[3] und [5] sind dann immer relevant.

    Könnte man auch sowas, wie Subarrays erreichen?

    Bei set dann  $matches[3][0] == 'EINS'
                  $matches[3][1] == 'ZWEI'
                  ...

    Wäre wirklich nett, wenn das nochmal jemand optimieren könnte. Die Reg_Exp sind für mich noch "Horror³"

    Nicht dass der Eindruck entsteht, ich würde drängeln wollen *nein gar nicht*
    Habe das nun nur schon seit ca. 14 Tagen versucht, mal Hilfe zu bekommen *umpf*

    Liebe Grüße aus http://www.braunschweig.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    1. Holladiewaldfee,

      #   bigint(20) unsigned
      #   set('EINS','ZWEI','DREI','VIER','FÜNF')
      #   float(11,10)
      #   enum('eins','zwei','sieben','12')

      Wie ich es machen würde:
      Zunächst mal würde ich ein Array mit Typen definieren (als Schlüssel) und als Wert den passenden regexp für den "Anhang". Also:

      $blubb = array('bigint' -> '/[1]{1,2})\w?(unsigned)?$/s',
                     'float' -> '/[2]{1,2}(,[0-9]{1,3})?)$/s',
                     ...)

      Dann würde ich den Typen mit explode an der öffnenden Klammer vom Schwanz hinten abtrennen:

      $bla = explode('(', $typ, 2);

      Überprüfung des Typs:
      if(isset($blubb[strtolower($bla[0])])) ...

      Überprüfung des Anhangs:
      if(preg_match($blubb[strtolower($bla[0])], $bla[1], $matches)) ...

      Dann kannst Du nach dem 2. if $matches verarbeiten

      Das Problem dürfte sein, den passenden Ausdruck für die enum- und set-Dinger zu schreiben. Vielleicht wühlst Du da einfach mal den phpMyAdmin Source-Code durch und schaust, wie die das gelöst haben.

      Ciao,

      Harry

      --
        Schnee :) Skitour gefällig?
        http://harry.ilo.de/projekte/berge/

      1. 0-9 ↩︎

      2. 0-9 ↩︎

      1. Hello,

        #   bigint(20) unsigned
        #   set('EINS','ZWEI','DREI','VIER','FÜNF')
        #   float(11,10)
        #   enum('eins','zwei','sieben','12')

        Wie ich es machen würde:
        Zunächst mal würde ich ein Array mit Typen definieren (als Schlüssel) und als Wert den passenden regexp für den "Anhang". Also:

        Das ist gar nicht dumm, weil das die Sicherheit gibt, dass nur definierte Typen erkannt werden können.

        $blubb = array('bigint' -> '/[1]{1,2})\w?(unsigned)?$/s',
                       'float' -> '/[2]{1,2}(,[0-9]{1,3})?)$/s',
                       ...)

        Dann würde ich den Typen mit explode an der öffnenden Klammer vom Schwanz hinten abtrennen:

        $bla = explode('(', $typ, 2);

        Das geht nicht, weil es ja auch welche gibt, die keine Längenangaben haben. Und unsigned Strings gibts nicht. Hate ich auch noch drüber nachgedacht, ob sowas passieren könnte. Ist dann aber ein Fehler.

        Überprüfung des Typs:
        if(isset($blubb[strtolower($bla[0])])) ...

        Überprüfung des Anhangs:
        if(preg_match($blubb[strtolower($bla[0])], $bla[1], $matches)) ...

        Dann kannst Du nach dem 2. if $matches verarbeiten

        Das Problem dürfte sein, den passenden Ausdruck für die enum- und set-Dinger zu schreiben. Vielleicht wühlst Du da einfach mal den phpMyAdmin Source-Code durch und schaust, wie die das gelöst haben.

        Das habe ich alles schon fertig und es funktioniert bestens. Da werden automatisch die <Select> oder die radio bzw. checkbox erstellt und auch wieder in Empfang genommen nach dem Post.

        Aber die Sache mit dem Type-Array ist wirklich nicht verkehrt.

        Liebe Grüße aus http://www.braunschweig.de

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen

        1. 0-9 ↩︎

        2. 0-9 ↩︎

        1. Holladiewaldfee,

          $bla = explode('(', $typ, 2);

          Das geht nicht, weil es ja auch welche gibt, die keine Längenangaben haben. Und unsigned Strings gibts nicht. Hate ich auch noch drüber nachgedacht, ob sowas passieren könnte. Ist dann aber ein Fehler.

          Dann trenn es mit preg_split am ersten Zeichen ab, das nicht [a-zA-Z] ist. Hauptsache, Du bekommst den Typ irgendwoher.

          Ciao,

          Harry

          --
            Schnee :) Skitour gefällig?
            http://harry.ilo.de/projekte/berge/
          1. Hello,

            Ich habe das jetzt mal mit dem Array versucht:

            #$metasum = "bigint(20) unsigned";
            $metasum = "set('EINS','ZWEI','DREI','VIER','FÜNF')";
            #$metasum = "double(11,5)";

            #$type="([a-z]{3,})";
            $type="tinyint|smallint|mediumint|int|bigint|float|double|decimal|".
                  "date|datetime|timestamp|time|year|char|varchar|tinyblob|".
                  "tinytext|text|blob|mediumblob|mediumtext|longblob|longtext|".
                  "enum|set";

            $len="([0-9]{1,3})";
            $dec=",([0-9]{1,3})";

            preg_match("#^($type){1}((([^)]+)))*(\s(unsigned){1})*#i",
               $metasum, $matches);

            echo "<pre>";
            print_r($matches);
            echo "</pre>";

            Aber wenn man da z.B. statt "set(...)" "seti(...)" übergibt, passt das ja auch. Wie bekomme ich denn hin, dass nur ganz exact die Typen matchen und dann erst eine Klammer oder ggf noch ein Leerzeichen, falls das in anderen MySQL-Versioenn noch so war) kommen muss?

            Liebe Grüße aus http://www.braunschweig.de

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            1. Holladiewaldfee,

              preg_match("#^($type){1}((([^)]+)))*(\s(unsigned){1})*#i",
                 $metasum, $matches);

              Aber wenn man da z.B. statt "set(...)" "seti(...)" übergibt, passt das ja auch. Wie bekomme ich denn hin, dass nur ganz exact die Typen matchen und dann erst eine Klammer oder ggf noch ein Leerzeichen, falls das in anderen MySQL-Versioenn noch so war) kommen muss?

              Ja, Du erlaubst das in Deinem Ausdruck ja auch, indem Du nicht darauf bestehst, daß der gesamte String mit obigem Muster erschlagen wird sondern das Ende offen lässt.

              Ich würde Dir immer noch raten zu versuchen, den Typen vom Rest abzutrennen.

              Ciao,

              Harry

              --
                Schnee :) Skitour gefällig?
                http://harry.ilo.de/projekte/berge/
              1. Hello,

                Ich würde Dir immer noch raten zu versuchen, den Typen vom Rest abzutrennen.

                Habe ich angenommen den Rat es mit zwei gestaffelten reg_split() gemacht. Die vollständige Funktion get_info ist noch etwas umständlich im Moment, aber das wird morgen noch repariert und dann auf den Server gepackt.

                Funktionieren tuts schon.

                Es werden jetzt vor allem nur noch die definierten Typen akzeptiert.

                Liebe Grüße aus http://www.braunschweig.de

                Tom

                --
                Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen