Anzahl bestimmter Wörter in einem String zählen

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Anzahl bestimmter Wörter in einem String zählen

    Hello again!

    Ich möchte aus einem String der ungefähr so aussieht.:
    Name1 | Name3 | Name2 | Name1 | Name1 | Name3 |
    ..die Anzahl jedes vorkommenden Wortes (Namex) zählen, und nach der Anzahl ordnen.
    Als Ergebnis sollte dann so etwas heraus kommen:
    [Name1][3]
    [Name3][2]
    [Name2][1]

    Hoffentlich versteht ihr wie ich das meine.
    Ich hab gesucht, und bin auf die function preg_match_all gestoßen.
    Allerdings verstehe ich diese nicht so ganz, bzw. weiss nicht, wie ich das pattern, wonach gesucht werden soll, der function mitgebe, denn das ist ja je nach String anders (-> immer unterschiedliche Namen:NameX).

    Wie soll ich da vorgehen?
    Eine Idee war den string in substrings auf zu teilen, dann jedes mit ner for schleife zu durchlaufen und jedes neu vorkommende worte in einen Array zuschreiben, dabei die Anzahl immer +1 zurechnen, und am Ende noch einen Sortieralgorythmus auszuführen.
    Das ist aber evtl. etwas aufwendig ^^

    Deshalb frage ich, gibt es eine php function die dies bereits für mich erledigt, und wenn ja: wie genau muss ich die einsetzen?

    Wäre sehr nett, wenn ihr mir weiterhelfen könntet:

    MfG

  • #2
    PHP-Code:

    $haystack 
    '...'// der zu durchsuchende Text

    // die Liste der zu suchenden Wörter
    $words = array (
        
    'word1''word2',
    );

    $stat = array (); // sammelt die Anzahl der Wörter

    foreach ($words as $word) {
        
    // bereite das zu suchende Wort als PCRE auf
        
    $pcre sprintf('/%s/'preg_quote($word));
        
    // Variante für Ignorieren von Groß-/Kleinschreibung
        //$pcre = sprintf('/%s/i', preg_quote($word));

        
    $num preg_match_all($pcre$haystack$hits);
        
    $stat[$word] = $num;
    }

    var_dump($stat); 
    Nachteile: Eventuell überlappende Wörter werden so mehrfach gezählt (in deinem Fall wahrscheinlich kein Problem). Und preg_match_all() legt bei jedem Durchgang ein extra Array in $hits an, dass alle gefundenen Wörter enthält. Das kann unter Umständen viel Speicher verbrauchen.

    *update*

    Eine Wortliste lässt sich so erzeugen:

    PHP-Code:
    $filter 'word1 | word2 | word3';

    $words preg_split('/\s+|\s+/'$filter); 
    *noch'n Update*
    Ich verweise gern darauf, dass man Lösungen mit preg_match() und seinen Verwandten meist unkomplizierter zwischen Groß-/Kleinschreibung-Ignorieren oder -Beachten umstellen kann. Aber hier geht das auch einfacher. Zumal mir beim ersten Durchlesen deines Posts entgangen ist, dass in deiner Aufgabenstellung "Wortliste" und "zu durchsuchender String" dasselbe sind. Deswegen hier noch eine Variante ohne preg_match_all():

    PHP-Code:
    // 'n Beispiel
    $words =  'word1 | word2 | word3 | word1 | WORD2 | wORD2';

    // callback für array_reduce()
    function reduce_helper(& $a$i) {
        if (!
    is_array($a)) {
            
    $a = array ();
        }
        
    // folgende Zeile auskommentieren,
        // wenn Grosz-/Kleinschreibung unterschieden werden soll
        
    $i strtolower($i);

        if (!isset (
    $a[$i])) {
            
    $a[$i] = 1;
        }
        else {
            
    $a[$i] += 1;
        }
        return 
    $a;
    }

    $stats array_reduce(
        
    preg_split('/\s+\|\s+/'$words),  // zerlegen
        
    'reduce_helper'                    // zaehlen
    );

    arsort($stats);

    var_dump($stats); 
    Wieso gibt's eigentlich keine fertige "count_words"-Funktion in PHP? Die haben doch sonst für jeden Quark was fertiggebackenes ...

    Ach so, str_word_count() zählt nicht, im doppelten Wortsinn: Wenn es ein Array zurückgeben soll, listet es nur die "Wörter" auf.

    PHP-Code:
    define('count_words_ignore_case'1);
    define('count_words_utf8'2);
    define('count_words_sort'4);

    function 
    count_words(
        
    $haystack,
        
    $mode /// 1: ignore case 0: case-aware 2: utf-8-mode 4: sort
    ) {
        
    $mode = (int) $mode;
        
    $pcre '/[\pL\pN]++/S' . ($mode 'i''') . ($mode 'u''');

        for (
            
    $off 0$stats = array ();
            
    preg_match($pcre$haystack$hitsPREG_OFFSET_CAPTURE$off);
            
    $off $hits[0][1] + strlen($hits[0][0])
        ) {
            
    $word $mode 2
                
    ? ($mode mb_strtolower($hits[0][0], 'UTF-8') : $hits[0][0])
                : (
    $mode strtolower($hits[0][0]) : $hits[0][0]);

            if (!isset (
    $stats[$word])) {
                
    $stats[$word] = 1;
            }
            else {
                
    $stats[$word] += 1;
            }
        }
        if (
    $mode 4) {
            
    arsort($stats);
        }
        return 
    $stats;

    Zuletzt geändert von fireweasel; 21.11.2010, 20:32.
    Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

    Kommentar


    • #3
      Wenn der Fall so simpel ist, wie dargestellt, könnte das hier reichen:
      PHP-Code:
      $words 'Name1 | Name3 | Name2 | Name1 | Name1 | Name3 | ';

      function 
      count_words($words){
          
      $words explode(' | ',$words);
          
      $counter = array();

          foreach(
      $words as $word)
              if(isset(
      $counter[$word]))
                  
      $counter[$word]++;
              else
                  
      $counter[$word] = 1;

          return 
      $counter;

      Kommentar


      • #4
        hallo fireweasel,
        danke für deine Antwort, die hat mir schon mal weitergeholfen

        Allerdings hab ich noch das Problem, dass ich die Wörter die im haystack gesucht werden sollen, vorher nicht kenne!
        Ich habe also einen String, in dem verschiedene Namen in unterschiedlicher Anzahl getrennt durch " | " vorkommen,
        weiss aber vorher nicht welche das sein werden.
        Das ist eigentlich mein Hauptproblem, wo ich nicht weiss wie ich das lösen soll.

        Noch eine Frage:
        Sortiert der Algorithmus auch das Ergebnis?

        MfG

        Kommentar


        • #5
          Allerdings hab ich noch das Problem, dass ich die Wörter die im haystack gesucht werden sollen, vorher nicht kenne!
          Ich habe also einen String, in dem verschiedene Namen in unterschiedlicher Anzahl getrennt durch " | " vorkommen,
          weiss aber vorher nicht welche das sein werden.
          Das ist eigentlich mein Hauptproblem, wo ich nicht weiss wie ich das lösen soll.
          Das ist in meinem bereits enthalten. Jetzt noch mal hingucken.

          Noch eine Frage:
          Sortiert der Algorithmus auch das Ergebnis?
          Offensichtlich nein! Woher hätten wir auch wissen sollen, wonach du es gerne sortiert haben möchtest. Selber mitdenken ist hier erlaubt!

          Kommentar


          • #6
            ah tut mir leid, wir hatten eben gleichzeitig gepostet.

            ja also dein Code (TobiaZ) funktioniert wunderbar, bis auf das sortieren, wie du schon meintest.

            Ich möchte es nach der Anzahl der vorkommenden Wörter sortieren.
            Beispiel: Name1 ist 1x vorhanden, Name2 10x und Name3 5x, dann sollte es so aus sehen:
            [Name2][10]
            [Name3][5]
            [Name1][1]

            Wie sortiere ich denn einen Array nach der 2. Spalte?
            sort und usort funktionieren hierbei irgendwie nicht =(

            MfG

            Kommentar


            • #7
              [Name2][10]
              [Name3][5]
              [Name1][1]
              Was soll das sein???

              Aber vermutlich suchst du arsort.
              Zuletzt geändert von TobiaZ; 21.11.2010, 16:37.

              Kommentar


              • #8
                ^ich wusste nicht genau wie ich es erklären sollte, aber arsort funktioniert, danke schön!

                Kommentar


                • #9
                  Naja, vielleicht mit einem gültigen Array-Dump? So sah es eher nach einem multidimensionalen Array aus...

                  Kommentar


                  • #10
                    substr_count()

                    Kommentar

                    Lädt...
                    X