2012-04-06 16 views
1

Ich brauche die Worte aus dieser Zeichenfolge greifen und ersetzen mit AND LIKE/NOT in einer SQL-Anweisung, aber ich ziehe mir die Haare auszuprobieren, es herauszufinden :-)php preg_match_all Syntax/regex

$string = "hello -world !someword ! again |foo &foo AND foo ORfoo"; 
if (preg_match_all("/AND|OR|\||&|!|\-(\w+)/", "$string", $matches)) { 
     foreach ($matches as $match) { 
       foreach ($match as $m) { 
         // 1. figure out what the delimiter was (!, |, &, -, AND, OR 
         // 2. create a sql statement from it using the word following the delimiter 
         // Example: 
         if ($m = "!") { 
           $where .= " AND msg NOT like '%".$m."%'"; 
         } 
         if ($m = "AND") { 
           $where .= " AND msg like '%".$m."%'"; 
         } 
         if ($m = "OR") { 
           $where .= " OR msg like '%".$m."%'"; 
         } 
       } 
     } 
} 
echo $where; 

Antwort

2

Verwenden Sie den folgenden Code, um Ihre Regex-Übereinstimmungen zu sammeln. Denken Sie daran, dass preg_match_all alle Vorkommen eines bestimmten Musters erfassen soll. Beachten Sie, dass ich stattdessen preg_match verwendet habe. Mit dem "\ s *" können Sie Whitespaces zuordnen, sofern sie existieren.

Sie können dann über das Array $ results iterieren, um Ihre MySQL-Abfrage zu erstellen. Das resultierende Array wird so aussehen.

Array 
(
    [0] => Array 
     (
      [0] => AND foo 
      [1] => AND 
      [2] => foo 
     ) 

    [1] => Array 
     (
      [0] => &foo 
      [1] => & 
      [2] => foo 
     ) 

    [2] => Array 
     (
      [0] => ORfoo 
      [1] => OR 
      [2] => foo 
     ) 

    [3] => Array 
     (
      [0] => |foo 
      [1] => | 
      [2] => foo 
     ) 

    [4] => Array 
     (
      [0] => !someword 
      [1] => ! 
      [2] => someword 
     ) 

    [5] => Array 
     (
      [0] => -world 
      [1] => - 
      [2] => world 
     ) 

) 

Ich fügte der Regex ein zusätzliches Capture hinzu. Ihre verschiedenen Mustern wird im Element 1 und das Wort wird in Element 2.

Sie den Code unten verwenden können Sie Ihre Abfrage-Fragment zu erstellen:

$query_fragment = ""; 
foreach($results as $r): 
    switch (trim($r[1])): 
     case "AND": 
      $query_fragment .= " AND msg LIKE '%" . $r[2] . "%'"; 
      break; 
     case "!": 
      $query_fragment .= " AND msg NOT LIKE '%" . $r[2] . "%'"; 
      break; 
     case "&": 
      $query_fragment .= " AND msg LIKE '%" . $r[2] . "%'"; 
      break; 
     case "OR": 
      $query_fragment .= " OR msg LIKE '%" . $r[2] . "%'"; 
      break; 
     case "|": 
      $query_fragment .= " OR msg LIKE '%" . $r[2] . "%'"; 
      break; 
    endswitch; 
endforeach; 
+0

das funktioniert, danke! –

+0

Sie sind herzlich willkommen. Es hat lange gedauert, bis ich den Regex in den Griff bekommen habe. Wenn Sie so freundlich wären, diese Antwort als die richtige Antwort zu markieren, würde ich es begrüßen. – Odyssey

1

Sie müssen den Trigger separat erfassen. Das ist:

/(AND|OR|\|&|!-)(\w+)/ 

Ihr Ausdruck erfasst derzeit nur ein Wort, das einem Bindestrich folgt.

Die Schleife ist ebenfalls falsch. Sie möchten etwas wie

foreach ($matches[1] as $count => $match) { 
    if ($match == '!') { 
     $where . = " AND msg NOT LIKE '%" . $matches[2][$count] . "%'"; 
    } 
} 

SQL-Injektion kann auch ein Anliegen für Sie sein.