| PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Post your PHP questions here! |
 |

21-11-2010, 13:45
|
|
w4rheart
Registrierter Benutzer
|
|
Registriert seit: Oct 2010
Beiträge: 20
|
|
Anzahl bestimmter Wörter in einem String zählen
Hello again!
Ich möchte aus einem String der ungefähr so aussieht.:
Zitat:
|
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
|

21-11-2010, 14:08
|
 |
fireweasel
Registrierter Benutzer
|
|
Registriert seit: Sep 2008
Ort: At home
Beiträge: 680
|
|
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 = 0 /// 1: ignore case 0: case-aware 2: utf-8-mode 4: sort
) {
$mode = (int) $mode;
$pcre = '/[\pL\pN]++/S' . ($mode & 1 ? 'i': '') . ($mode & 2 ? 'u': '');
for (
$off = 0, $stats = array ();
preg_match($pcre, $haystack, $hits, PREG_OFFSET_CAPTURE, $off);
$off = $hits[0][1] + strlen($hits[0][0])
) {
$word = $mode & 2
? ($mode & 1 ? mb_strtolower($hits[0][0], 'UTF-8') : $hits[0][0])
: ($mode & 1 ? 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;
}
__________________
PHP-Code:
class Brick implements Throwable {
// ...
}
Geändert von fireweasel (21-11-2010 um 20:32 Uhr)
|

21-11-2010, 14:45
|
TobiaZ
 Moderator
|
|
Registriert seit: Jan 2001
Ort: MUC und MGL, Germany
Beiträge: 34.188
|
|
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;
}
|

21-11-2010, 14:45
|
|
w4rheart
Registrierter Benutzer
|
|
Registriert seit: Oct 2010
Beiträge: 20
|
|
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
|

21-11-2010, 14:56
|
TobiaZ
 Moderator
|
|
Registriert seit: Jan 2001
Ort: MUC und MGL, Germany
Beiträge: 34.188
|
|
Zitat:
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.
Zitat:
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!
|

21-11-2010, 15:31
|
|
w4rheart
Registrierter Benutzer
|
|
Registriert seit: Oct 2010
Beiträge: 20
|
|
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
|

21-11-2010, 16:34
|
TobiaZ
 Moderator
|
|
Registriert seit: Jan 2001
Ort: MUC und MGL, Germany
Beiträge: 34.188
|
|
Zitat:
[Name2][10]
[Name3][5]
[Name1][1]
|
Was soll das sein???
Aber vermutlich suchst du arsort.
Geändert von TobiaZ (21-11-2010 um 16:37 Uhr)
|

21-11-2010, 16:52
|
|
w4rheart
Registrierter Benutzer
|
|
Registriert seit: Oct 2010
Beiträge: 20
|
|
^ich wusste nicht genau wie ich es erklären sollte, aber arsort funktioniert, danke schön!
|

21-11-2010, 16:54
|
TobiaZ
 Moderator
|
|
Registriert seit: Jan 2001
Ort: MUC und MGL, Germany
Beiträge: 34.188
|
|
Naja, vielleicht mit einem gültigen Array-Dump?  So sah es eher nach einem multidimensionalen Array aus...
|

21-11-2010, 17:19
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.481
|
|
substr_count()
|
|
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
|
|
|
| Themen-Optionen |
|
|
| Thema bewerten |
|
|
Forumregeln
|
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
HTML-Code ist aus.
|
|
|
|
PHP News
|