PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : regexp und mysql: escapen von sonderzeichen


feuervogel
13.01.2004, 21:31:39
hallo!

ich hab mal wieder ein problemchen: ich durchsuche mit regexps eine mysql-datenbank...ich weiß, die syntax ist recht krankhaft, aber es ist einfach schneller als die regex-engine in php anzuschmeißen...

ich durchsuche die beiträge eines forums, und zwar auf den anfangsbuchstaben des inhalts. wenn aber nun ein format-tag davor steht, soll dieser nicht berücksichtigt werden, ebenso wie leerzeichen nicht.

$sql = "SELECT * FROM board WHERE trashcan = '0' AND content REGEXP '^[[:space:]]*([.*])*[[:space:]]*(m).*$' ";

"m" steht für einen anfangsbuchstaben...

folgendes wird nicht gematched: "[code]mumu"

mache ich ienen fehler beim escapen der eckigen klamern? oder was mach ich falsch?

Fuchs
14.01.2004, 19:32:12
Naja das ganze ist jetzt noch ein 'parser' tiefer wie bei php's regexe.

Du kennst ja sicherlich den Code wenn du in php einen RE schreibst:

preg_*('@n@'..)

dann parst ja zuerst php den String und dann PCRE. Sprich das oben ist ein NL in diesem Fall.

Bei deinem Fall macht der PHP Parser in diesem Fall zwar nichts weil [ PHP 'egal' ist und dabei nichts veraendert aber gleich fuer die Zukunft:

Folgendes spielt sich in dieser Reihenfolge ab:

Zuerst kommt PHP angedackelt, parst den String und macht aus allen sonderzeichen (sihe Manual) z.B. n ein Zeilenumbruch:

echo "foonbar";
//Ausgabe:
//foo
//bar

echo "foo[bar"; // foo[bar

Danach kommt noch unser heis geliebter MySQL parser den den String nochmal parst:

mysql> select '';
+---+
| |
+---+
| |
+---+
1 row in set (0.00 sec)

mysql> select 'foo bar [lal';
+--------------+
| foo bar [lal |
+--------------+
| foo bar [lal |
+--------------+
1 row in set (0.00 sec)

MySQL's parser parst also anders wie unser PHP'ler. (Beachte: aus [ in PHP wurde [, aus [ in MySQL wurde [)

So nun ist schaut dein regex in mysql also so aus:

mysql> select '^[[:space:]]*([.*])*[[:space:]]*m';
+-----------------------------------+
| ^[[:space:]]*([.*])*[[:space:]]*m |
+-----------------------------------+
| ^[[:space:]]*([.*])*[[:space:]]*m |
+-----------------------------------+
1 row in set (0.00 sec)

Sprich wir muessen -damit die BackSlashes persistieren- die Backslashes mit Backslashes escapen:

mysql> select '^[[:space:]]*([.*])*[[:space:]]*m';
+-------------------------------------+
| ^[[:space:]]*([.*])*[[:space:]]*m |
+-------------------------------------+
| ^[[:space:]]*([.*])*[[:space:]]*m |
+-------------------------------------+
1 row in set (0.00 sec)

Das duerfte unser erwuenschtes Ergebnis sein.


So, nun sind wir aber noch nicht am ende mit der parserei. Jetzt kommt als aller letztes noch unser RE Parser und macht aus allen n z.B. 'echte' Linefeeds, was in deinem Fall aber irrelevant ist.

Zu guter letzt der Funktionierende Query:


mysql> select ' [foo]mumu' REGEXP '^[[:space:]]*([.*])*[[:space:]]*m';
+-------------------------------------------------------------+
| ' [foo]mumu' REGEXP '^[[:space:]]*([.*])*[[:space:]]*m' |
+-------------------------------------------------------------+
| 1 |
+-------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

So in deinem Fall ist es noch relativ einfach. (Da du nur ein [ innerhalb der RE Engine escapen willst).

So als kleine Lernaufgabe will ich dafuer ein Query der auf den String 'n' mittels _REGEXP_ matcht. Und zwar aus PHP heraus mit Double quotes:

$sql = ".... REGEXP 'n'";

Das ist der Anfang. ;)

Have Fun, Andre

//edit:

Der Funktionierende Query ist in PHP ncoh um eins mehr escapet. Da in PHP (auch in Single Quotes) aus ein wird.

$sql = '... \[....';

echo $sql; // ... [.... -> bekommt MySQL.

feuervogel
14.01.2004, 20:48:21
also ich hab mir das jetzt mal überflogen, aber ich weiß nicht, ob du irgendwas falsch verstanden hast...? da ist noch gar nix geparsed, von keinem php und gar nix.

die daten stehen so roh in der db:

[code]mumu usw. usf...

werde mir heute abend aber das ganze nochmal genauer durchlesen, vielleicht hab ich ja nur grad was nicht kapiert! vielen dank schon mal für die (doch sehr lange) hilfe!

Fuchs
14.01.2004, 22:18:04
Wenn du nicht nur dieses Problem geloest bekommen werden willst, sondern in Zukunft deine Probleme (in Zusammenhang mit diesem Thema) selber loesen willst, dann soltest du dir das nochmal in Ruhe durchlesen und schritt fuer schritt alles verstehen. Das oben Beschriebene ist Grundlegend und kann auf verschiedene Sachen transformiert werden.

Ich hab da mal letztes einen guten Spruch gelesen:

--
Gib einem Hungrigen einen Fisch, und er ist für einen Tag satt.
Zeig ihm, wie man angelt, und er pöbelt Dich an, dass er besseres
zu tun hätte, als Schnüre ins Wasser hängen zu lassen.
[David Kastrup in de.comp.text.tex]