Autocomplete mit Wörter aus einem Text (DB)

slimox

Mitglied
Hallo,

Da steht ich schon wieder an.. ;) Es gibt eine DB-Tabelle mit Spalte "Name" und Spalte "Text1". Jetzt habe ich eine einfaches Input-Feld mit welchem in der DB gesucht werden kann. Gibt Jemand jedoch ein Wort ein, welches nicht im Name oder Text vorkommt so findet es nicht. Logisch ;)

Meine Idee: Mit jQuery Autocomplete laufend Name oder Wörter aus dem Text1 einblenden, in welchen der Suchbegriff vorkommt.

Wenn ich nur im Feld "Name" suche ist das auch keine Sache, dann gebe ich einfach den ganzen Namen aus.

Das Problem: Eine SQL Abfrage, welche im Name und im Text1 sucht. Findet es im Text1 den Suchbegriff, dann mit PHP nur die Wörter vom Text1 ausgeben in welchen der Suchbegriff vorkommt.

SQL für Test:
Code:
--
-- Tabellenstruktur für Tabelle `dbsuche`
--

CREATE TABLE IF NOT EXISTS `dbsuche` (
  `id` int(11) NOT NULL auto_increment,
  `name` text NOT NULL,
  `text1` text NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

--
-- Daten für Tabelle `dbsuche`
--

INSERT INTO `dbsuche` (`id`, `name`, `text1`) VALUES
(1, 'Äpfel', 'Die Äpfel (Malus) bilden eine Pflanzengattung der Kernobstgewächse (Pyrinae) au'),
(2, 'Birnen', 'Die Birnen (Pyrus) bilden eine Pflanzengattung, die zu den Kernobstgewächsen'),
(3, 'Banane', 'Banane steht für: Bananen (Musa), eine Gattung in der Familie der Bananengewächse');

Abfrage
PHP:
$woerter = array();

$sql = "SELECT
            name, text1,
            IF( name  REGEXP '$search', 3, 0 ) AS inName,
            IF( text1  REGEXP '$search', 1, 0 ) AS inText1
        FROM
            dbsuche
        WHERE
            name REGEXP '$search'
        OR
            text1 REGEXP '$search'
        ORDER BY
            (inName + inText1)
        DESC
        LIMIT 10";

$query = $this->db->query($sql);
foreach ($query->result() as $row){
    //Wenn im Namen gefunden
    if($row->inName >= 3){
        $woerter[] = $row->name;
    }
    
    //Wenn im Text gefunden
    if($row->inText1 >= 1){
        //Wie bekomme ich nur die Wörter in denen der Suchbegriff ist?
        $row->text1;
    }
}

In der VAR $row->text1 ist der ganze Text. Wie bekomme ich nur die Wörter in denen auch der Suchstring passt? :rolleyes:

Gibt Jemand "Banan" ein so sollte es diese Wörter ausspucken:
Banane, Bananen, Bananengewächse

Für alle AW's dankbar!
 
Zuletzt bearbeitet:
Oder du verwendest preg_match_all, die Treffer landen dann in einem Array. Wenn ich das richtig verstanden hab könntest du dafür denselben regulären Ausdruck verwenden, den du schon in der Abfrage drin hast.

@stutz: müsste hier
SQL:
WHERE
 name REGEXP '$search'
AND
 text1 REGEXP '$search'
nicht ein OR stehen?
 
Zuletzt bearbeitet von einem Moderator:
Ich steh mit regulären Ausdrücken n bisschen auf Kriegsfuß...

Was hast du denn in $search drin? Das sollte sich doch schonmal als Basis nutzen lassen. Nach meiner Vorstellung müsstest du "nur" zusätzlich regeln, dass die Treffer vom vorherigen bis zum nächsten Leerzeichen gehen müssen, damit du eben die kompletten Wörter hast.

Aber da kann ich nicht dran mitbauen, sorry.

@post: Sorry, hatte mich durch das REGEXP im Query darauf bringen lassen...
 
Zuletzt bearbeitet:
Vielleicht so:

PHP:
$string = "Banane";
$pattern = '/.*(anan)*/';
preg_match($pattern, $string, $matches);

edit, sorry so kannst nicht funktionieren. ich habs nur mit dem String "Banane" getestet.

edit2: so sollte es gehen
PHP:
$string = "Ich bin eine gerade Banane und hab keinen Bogen";
$pattern = '/[^ ]('.$search.')[^ ]/';
preg_match($pattern, $string, $matches);
 
Zuletzt bearbeitet:
Was hast du denn in $search drin?
Code:
$search = 'anan';

Es ist nicht wichtig was in search steht. Ist der Suchbegriff und könnte auch 'Bana' oder so sein :D

Ja, die Lösung mit Leerzeichen trennen geht nicht, da das Wort auch am Satzende stehen kann ,.!? Der Text ist HTML-Formatiert also auch <> sind möglich;) :rolleyes:

edit2: so sollte es gehen
PHP:
$string = "Ich bin eine gerade Banane und hab keinen Bogen";
$pattern = '/[^ ]('.$search.')[^ ]/';
preg_match($pattern, $string, $matches);

Wie ist es möglich vor und nach dem Wort ein Leerzeichen und |,|.|?|!|<|>| :eek:
 
Zuletzt bearbeitet von einem Moderator:
Bei mir findet es auch eine Banane :)
Code:
Banane steht für: Bananen (Musa), eine Gattung in der Familie der Bananengewächse! Wo so..
PHP:
        $pattern = '/[^ ]('.$search.')[^ ]/';
        preg_match($pattern, $row->text1, $treffer);
        var_dump($treffer);
Code:
array(2) { [0]=> string(6) "Banane" [1]=> string(4) "anan" }

Es sollte aber: Banane, Bananen, Bananengewächse finden. Bin am ReguläreA. am durchlesen :eek:
 
So, das pattern sieht jetzt so aus
PHP:
$pattern =   '/\b([\wöäü]*'.$search.'[\wöäü]*)\b/i';

ein weiterer Fehler war preg_match( jetz ist preg_match_all( am laufen
PHP:
$search = 'anan';
$woerter = array();

$sql = "SELECT
            name, text1,
            IF( name  REGEXP '$search', 3, 0 ) AS inName,
            IF( text1  REGEXP '$search', 1, 0 ) AS inText1
        FROM
            dbsuche
        WHERE
            name REGEXP '$search'
        OR
            text1 REGEXP '$search'
        ORDER BY
            (inName + inText1)
        DESC
        LIMIT 10";

$query = $this->db->query($sql);
foreach ($query->result() as $row){
    //Wenn im Namen gefunden
    if($row->inName == 3){
        //Wenn das Wort noch nicht im Array
        if(!in_array($row->name, $woerter)) {
            $woerter[] = $row->name;
        }
    }
    
    //Wenn im Text gefunden
    if($row->inText1 == 1){
        $pattern =   '/\b([\wöäü]*'.$search.'[\wöäü]*)\b/i';
        preg_match_all($pattern, $row->text1, $treffer);
        //Alle Treffer 
        foreach($treffer[0] as $value){
            //Wenn das Wort noch nicht im Array
            if(!in_array($value, $woerter)) {
                $woerter[] = $value;
            }
        }
    }
} 

var_dump($woerter);

und es gibt alle möglichen Bananen zurück
Code:
array(3) {
  [0]=>
  string(6) "Banane"
  [1]=>
  string(7) "Bananen"
  [2]=>
  string(16) "Bananengewächse"
}
:D
 
Zurück