NOOB: PHP Multiarray aus Json-> Suchen und sicher finden (auch bei Fragmenten)

Hallo,

ich fange mal direkt mit der Problemstellung an. Ich habe in einem Multiarray $row['ueberschrift'] die Bsp. enthält "Schoen war der Urlaub in Kroatien".

Ich habe jetzt einen Querry "war der Urlaub in Kroatien". Bei einer Prüfung mit dem == Operator wird es korrekt nicht gefunden.

Ich habe es mit https://www.php.net/manual/de/function.strpos.php probiert, und es funktioniert.

Sicher haben die Profis hier 10x schneller und bessere Ideen.

  1. Hallo NOOB,

    suchst Du nach einer Alternative für eine Prüfung auf "Ist String A in String B enthalten"?

    Mit strpos bekommst Du außer der Aussage "Ist enthalten" auch noch die Aussage "Findet sich an Position ...". Wenn Du das nicht brauchst, gibt's auch noch str_contains.

    Beide Funktionen arbeiten

    • case sensitive (also "schön" und "Schön" sind nicht gleich)
    • byteweise und nicht zeichenweise. Da das Web heute mit Unicode funktioniert und Unicode-Strings UTF-8 codiert in PHP ankommen, führen die alten Funktionen, die byteweise operieren, ggf. in Probleme.

    Prüfe deine Webseite. Wenn Du, wie es sein sollte, mit UTF-8 arbeitest, solltst Du die mb_-Stringfunktionen verwenden.

    Für eine Suche, die case-insensitive arbeiten soll, gibt es stripos. Aber das fällt Dir schnell auf die Füße. Diese Funktion kommt mit Umlauten nicht klar. Und ein str_icontains gibt's gar nicht.

    mb_stripos funktioniert dagegen korrekt mit Unicode und ist case-insensitive bei deutschen Umlauten

    Dazu gibt mb_stripos("In Österreich war es schön", "schön") auch korrekt 21 aus, während strpos das Ö von Österreich als 2 Zeichen zählt (weil es in UTF-8 zwei Bytes sind).

    Kompliziert? JA! Sorry. Zeichencodierung ist eine ganz spezielle Hölle für sich.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. @@Rolf B

      mb_stripos funktioniert dagegen korrekt mit Unicode und ist case-insensitive bei deutschen Umlauten

      Und das sogar besser als erwartet. Nicht nur Umlaute, auch großes ẞ:

      echo mb_stripos('SCHÖN', 'ö'); // 3  ► play

      echo mb_stripos('schön', 'Ö'); // 3play

      echo mb_stripos('GROẞ', 'ß'); // 3play

      echo mb_stripos('groß', 'ẞ'); // 3play

      😷 LLAP

      --
      „Guten Tag, mein Name ist Karl-Heinz. Ich will mich nicht impfen lassen und erwarte, dass die Solidargemeinschaft, die wegen Leuten wie mir weniger Freiheit hat, meine Tests weiter finanziert. Und das nenne ich dann Eigenverantwortung.“
      — @Hoellenaufsicht
      1. Ergänzend:

        Falls die Suche etwas komplizierter oder ungenauer oder genauer sein soll und geringfügig langsamer sein darf (also maximal ein paar Megabytes an Strings durchsucht werden) bietet sich noch die Funktion preg_match() (und ) an. Die hat dann auch noch Schwestern, die man (bei genügend großem Bildschirm) ganz rechts sieht).

        Einfachster Fall:

        <?php
        
        $searchstr = 'Bar';
        $needle    = '/' . str_replace( '/', '\/', $searchstr ) . '/i';
        $heystack  = 'foobarbaz';
        
        
        if ( preg_match( $needle, $heystack, $matches  ) ) {
            echo 'Nadel im Heuhaufen gefunden: "' . $matches[0] . '"' . PHP_EOL;
        } else {
            echo 'Nicht gefunden: "' . $searchstr . '"'  . PHP_EOL;
        }
        
        
        1. Hallo Raketenwissenschaftler,

          wäre mb-ereg-match nicht besser? Ist zwar noch ein bisschen langsamer, aber dafür Unicode-fähig.

          Rolf

          --
          sumpsi - posui - obstruxi
          1. Hallo Raketenwissenschaftler,

            wäre mb-ereg-match nicht besser?

            Naja. Solange nicht nach 'J[öü]rg' gesucht wird klappt es auch mit preg_match() - Voraussetzung ist natürlich, dass Programm und Daten identisch kodiert sind.

            <?php
            
            $searchstr = 'J[öü]rg';
            $heystack  = 'JÖRG ANDREA PAUL';
            mb_regex_encoding('UTF-8');
            mb_regex_set_options('ix'); #GROSS/KLEIN + Erweiterte Regexe
            
            if ( mb_ereg_match( $searchstr, $heystack )  ) {
                echo 'Nadel im Heuhaufen gefunden: "' . $searchstr . '"' . PHP_EOL;
            } else {
                echo 'Nicht gefunden: "' . $searchstr . '"'  . PHP_EOL;
            }
            

            Es wäre dann noch mb_ereg() zu empfehlen. Da kann man wie oben gezeigt, die Fundstellen in ein Array schreiben lassen. Zudem wäre noch mb_eregi()

          2. Hi,

            wäre mb-ereg-match nicht besser?

            bietet (mb-)ereg-match denselben Funktionsumfang wie preg-match?

            Die Doku der Funktionen schweigt sich da leider aus - kein Link auf die (jeweilige) Pattern-Syntax, beim pattern-Parameter heißt es nur "The pattern to search for, as a string. "

            (ok, unter "See also" findet sich bei preg_match dann doch ein Link zur PCRE-Doku - der gehört m.E. in die Beschreibung des pattern-Parameters - aber bei mb_ereg_match find ich da keinerlei Hinweis)

            Ich meine, früher, als es auch noch ereg_match (ohne mb) gab, hatte das einen deutlich geringeren Umfang an Möglichkeiten beim Pattern als preg_match.

            cu,
            Andreas a/k/a MudGuard

            1. Tach!

              bietet (mb-)ereg-match denselben Funktionsumfang wie preg-match?

              Die Doku der Funktionen schweigt sich da leider aus - kein Link auf die (jeweilige) Pattern-Syntax, beim pattern-Parameter heißt es nur "The pattern to search for, as a string. "

              PHP besteht neben dem Kern der Sprache aus Extensions, in denen die Funktionen eines bestimmten Themas zusammengefasst sind. Die PHP-Dokumentation trägt dem Rechnung, indem sie wie ein Buch aufgebaut ist, in dem jede Extension ihr eigenes Kapitel hat. Diese bestehen wiederum aus allgemeinen Informationen zur Extension und den Beschreibungen der Funktionen. Die Patternsyntax ist allgemeine Information und steht in ihrem eigenen Unterkapitel im Kapitel zur PRCE-Extension. In der Breadcrumb-Navigation kommt man recht einfach auf die übergeordneten Kapitel.

              Ansonsten, ja, ein Link zur Syntax bei der Parameterbeschreibung hätte nicht geschadet. Leider gibts keine Möglichkeit mehr, Feedback einfach zu hinterlassen.

              (ok, unter "See also" findet sich bei preg_match dann doch ein Link zur PCRE-Doku - der gehört m.E. in die Beschreibung des pattern-Parameters - aber bei mb_ereg_match find ich da keinerlei Hinweis)

              Ich hab im Netz noch alte Kopien der PHP-Dokumentation gefunden, darin gibt es selbst im POSIX-Regex-Kapitel keine Dokumentation der Syntax. Da es aber ein Standard ist, findet man Dokumentation anderenorts. MySQL beispielsweise nutzt diese Syntax für ihre Regex-Funktionen.

              Ich meine, früher, als es auch noch ereg_match (ohne mb) gab, hatte das einen deutlich geringeren Umfang an Möglichkeiten beim Pattern als preg_match.

              Da die POSIX-Regex-Extension seit PHP 7.0 entfernt ist, wurde auch irgendwann das Kapitel aus der Dokumentation genommen. Warum diese Regexe doch noch als Teil der Multibyte-Strings-Extension vorhanden sind, ist eigenartig. Immerhin kann man dort optional auswählen, welchen von acht Syntax-Modes man haben möchte. Beschreibungen oder verlinkte Dokumentation findet man da aber nicht, außer PCRE in dessen Kapitel.

              PCRE bietet zwar mehr Möglichkeiten als POSIX, aber Regexe sind Mustersuchen. Die Unicode-Fähigkeiten beschränken sich bei PCRE lediglich darauf, dass man Zeichen gemäß bestimmter Eigenschaften (ist Buchstabe, Ziffer, Punktuation etc.) suchen kann. Es ist leider kein Vergleich zu beispielsweise MySQLs Möglichkeiten, die die Kollationen bieten, bei denen man zu den Basisbuchstaben auch die diakritischen Varianten finden kann.

              dedlfix.