Julchen: & MySQL & RegEx: Assertions in Datenbankabfrage?

Guten Morgen ;)

ich bastel' seit gestern an einer MySQL-Datenbankabfrage, die mir alle Tabellenzeilen ausgeben soll, in deren Spalte "spalte" unter anderem die Zeichenkette 1x2 vorkommt. Das klappt soweit auch mit folgender Abfrage:

"SELECT * FROM tabelle WHERE spalte REGEXP '1x2'"

Allerdings möchte ich ausschließen, dass auch Spalten gefunden werden, in denen z.B. 1x20 steht...

Bei "normalen" RegExen kann ich ja eine Assertion a la 1x2(?![0-9]) machen...allerdings wird bei der Datenbankabfrage das "?" als Wiederholungs-Operator und nicht als Assertion interpretiert...

Gibt es eine Lösung mit der ich Assertions auch in Datenbankabfragen verwenden kann?

Danke schonmal für's Lesen ;)
Julchen

  1. ...manchmal hilft's scheinbar schon, wenn man einfach mal aufschreibt, welches Problem man hat ;) Ich hab' das ganze jetzt folgendermaßen gelöst:

    "SELECT * FROM tabelle WHERE spalte REGEXP '1x2[^0-9]' OR '[^0-9]1x2'"

    Julchen wünscht ein schönes, langes Osterwochenende ;)

    1. Moin!

      ...manchmal hilft's scheinbar schon, wenn man einfach mal aufschreibt, welches Problem man hat ;) Ich hab' das ganze jetzt folgendermaßen gelöst:

      "SELECT * FROM tabelle WHERE spalte REGEXP '1x2[^0-9]' OR '[^0-9]1x2'"

      Kann mir kaum vorstellen, dass das schon die finale korrekte Lösung ist.

      Wenn du nach "1x2" suchst, und ausschließen willst, dass vor der 1 noch Ziffern kommen, und auch nach der 2, dann ist das EIN regulärer Ausdruck für mich.

      Und auch deine WHERE-Bedingung schaut extrem merkwürdig aus. Es gibt nämlich keine REGEXP-Verknüpfung mit OR. Das, was du da produziert hast, ist folgendes (geklammert zur Verdeutlichung):
      (spalte REGEXP '1x2[^0-9]') OR ('[^0-9]1x2')

      Also der Regex-Vergleich oder ein konstanter String. Wundert mich, dass das ohne Fehlermeldung durchgeht.

      - Sven Rautenberg

      --
      "Love your nation - respect the others."
      1. Hallo ;)

        "SELECT * FROM tabelle WHERE spalte REGEXP '1x2[^0-9]' OR '[^0-9]1x2'"

        Kann mir kaum vorstellen, dass das schon die finale korrekte Lösung ist.

        Wenn du nach "1x2" suchst, und ausschließen willst, dass vor der 1 noch Ziffern kommen, und auch nach der 2, dann ist das EIN regulärer Ausdruck für mich.

        Und auch deine WHERE-Bedingung schaut extrem merkwürdig aus. Es gibt nämlich keine REGEXP-Verknüpfung mit OR. Das, was du da produziert hast, ist folgendes (geklammert zur Verdeutlichung):
        (spalte REGEXP '1x2[^0-9]') OR ('[^0-9]1x2')

        Also der Regex-Vergleich oder ein konstanter String. Wundert mich, dass das ohne Fehlermeldung durchgeht.

        • Sven Rautenberg

        DANKE für Deine Antwort ;) Und Du hattest Recht! Im phpmyadmin hat meine Lösung oben zwar ohne meckern funktioniert, aber in der php-Datei sah das Ergebnis merkwürdig aus!

        Ich hab's nochmal anders geschrieben - und zwar folgendermaßen:
        $abfrage = "SELECT * FROM tabelle WHERE spalte REGEXP '(1x2[^0-9])|([^0-9]1x2)|(^1x2$)'";

        Scheinbar müssen die [ escaped werden, damit's klappt - das war mir auch noch nicht so klar...

        Ich bin natürlich für jede weitere Kritik offen - man lernt immer dazu! ;)

        Julchen

        1. Moin!

          Ich hab's nochmal anders geschrieben - und zwar folgendermaßen:
          $abfrage = "SELECT * FROM tabelle WHERE spalte REGEXP '(1x2[^0-9])|([^0-9]1x2)|(^1x2$)'";

          Du suchst also nach Einträgen, die folgende Form haben:
          ...4321x2...
          oder
          ...1x2345...
          oder exakt
          1x2

          Das klingt mir nicht nach dem, was du vorher beschrieben hast.

          Scheinbar müssen die [ escaped werden, damit's klappt - das war mir auch noch nicht so klar...

          MySQL und REGEXP erfordern unter Umständen doppeltes Escaping. Zumindest wenn man will, dass die Backslashes bei der REGEXP-Engine ankommen. Steht aber auch so im Handbuch: http://dev.mysql.com/doc/refman/4.1/en/regexp.html

          - Sven Rautenberg

          --
          "Love your nation - respect the others."
          1. Hi,

            Du suchst also nach Einträgen, die folgende Form haben:
            ...4321x2...
            oder
            ...1x2345...
            oder exakt
            1x2

            Das klingt mir nicht nach dem, was du vorher beschrieben hast.

            • Sven Rautenberg

            hmm...merkt man, dass ich nicht viel mit RegExen mache?!?  :) Aber ich hab nochmal was neues erbastelt, und zwar:

            $abfrage = "SELECT * FROM tabelle WHERE spalte REGEXP '(([^0-9]|-|^)1x2([^0-9]|-|$))'";

            Denn die zu durchsuchende Zeichenkette in der Tabelle sieht z.B. so aus: 1x2-77x36-12x44-4x7-12x33...vielleicht steh' ich immernoch auf dem Schlauch. Aber im Moment funktionierts... Ich hab' ja ein langes Wochenende vor mir an dem ich viel Zeit mit lesen verbringen kann ;)

            Julchen

            1. hups...einmal zuviel geklammert...

              $abfrage = "SELECT * FROM tabelle WHERE spalte REGEXP '([^0-9]|-|^)1x2([^0-9]|-|$)'";