|
|
 |
substr_count (PHP 4, PHP 5) substr_count -- Count the number of substring occurrences Descriptionint substr_count ( string haystack, string needle )
substr_count() returns the number of times the
needle substring occurs in the
haystack string. Please note that
needle is case sensitive.
Example 1. substr_count() example |
<?php
echo substr_count("This is a test", "is"); ?>
|
|
See also count_chars(),
strpos(), substr(),
and strstr().
User Contributed Notes
substr_count
jsb17 at cornell dot edu
03-Oct-2004 06:42
In response to Jesse at bend dot com's comment regarding case insensitivity, if your substr_count() function is in a loop, never implement this:
<?php
for($i=0; $<$n_needles; $i++){
substr_count(strtolower($haystack), strtolower($needle[$i]));
} ?>
I recommend implementing this instead:
<?php
$haystack_lower = strtolower($haystack);
for ($i=0; $<$n_needles; $i++){$needle[$i] = strtolower($needle[$i]);} for($i=0; $i<$n_needles; $i++){
substr_count($haystack_lower, $needle[$i]); } ?>
An example of the aforementioned arises if you are implementing, for instance, a search function in a help manual, when you check each user-entered search word against the manual text (like at the top of this page), and count the number of occurrences of each search word to weigh your results so you can display the best results first.
If the above code is within ANOTHER loop traversing each of many manual pages, then you'll definitely get hammered on the iterative strtolower() process time. Always try to keep strtolower() outside the outermost loop, and query using use "SELECT LOWER(manual_text) FROM..." instead.
Maybe this comment belongs in the strtolower() documentation?
McAjvar
03-Sep-2004 05:15
this is a small correction of bpotter's code:
if (substr_count($QUERY_STRING, '&') > 0) {
$QUERY_STRING = str_replace('&', '&', $QUERY_STRING);
$queryArray = explode('&',$QUERY_STRING);
foreach ($queryArray as $queryItem) {
$querySegment = explode("=",$queryItem,2);
list ($key, $val) = $querySegment ;
if ($val)
$$key = $val;
}
}
explanation: these corrections do not replace
file.php?var1=using winamp; others suck&var2=1+1=2&var3=mongolia
into
file.php?var1=using win others suck&var2=1+1=2&var3=mongolia
but rather into
file.php?var1=using winamp; others suck&var2=1+1=2&var3=mongolia
also, the when having values which also contain '=', the parameter 2 in explode () prevents it into splitting it in more than 2 values. so $var2 isn't an array ('1+1', '2') but rather has the value '1+1=2'
hope this helps :)
XinfoX X at X XkarlX X-X XphilippX X dot X XdeX
21-Dec-2003 03:27
Yet another reference to the "cgcgcgcgcgcgc" example posted by "chris at pecoraro dot net":
Your request can be fulfilled with the Perl compatible regular expressions and their lookahead and lookbehind features.
The example
$number_of_full_pattern = preg_match_all('/(cgc)/', "cgcgcgcgcgcgcg", $chunks);
works like the substr_count function. The variable $number_of_full_pattern has the value 3, because the default behavior of Perl compatible regular expressions is to consume the characters of the string subject that were matched by the (sub)pattern. That is, the pointer will be moved to the end of the matched substring.
But we can use the lookahead feature that disables the moving of the pointer:
$number_of_full_pattern = preg_match_all('/(cg(?=c))/', "cgcgcgcgcgcgcg", $chunks);
In this case the variable $number_of_full_pattern has the value 6.
Firstly a string "cg" will be matched and the pointer will be moved to the end of this string. Then the regular expression looks ahead whether a 'c' can be matched. Despite of the occurence of the character 'c' the pointer is not moved.
bishop
03-Dec-2003 06:42
Here is a simple item frequency counter function, useful in reporting or statistical apps:
<?php
function count_item(&$freq, $item, $inc = 1) {
if (! is_array($freq)) {
$freq = array ();
}
$freq[$item] = (isset($freq[$item]) ? ($freq[$item] += $inc) : $inc);
return true;
}
?>
This function saves you the hassle of doing the isset() check each time you wish to increase the frequency. If you're not normally concerned over PHP's warnings about uninitialized variables, then you should probably start from the beginning. If you are, use the function above like:
<?php
count_item($freq, 'foo');
count_item($freq, 'bar');
count_item($freq, 'foo');
?>
After this, $freq will equal array ('foo' => 2, 'bar' => 1)
W Chee Wee
21-Jun-2003 01:18
With reference to the "cgcgcgcgcgcgc" example, u can treat the string as a queue and just pop out the first character in iterations. You will get a return value of 6, thus allowing for overlapping.
Big daddy Programming
02-Apr-2003 11:16
3 is right. It should not return 6. If it is starting from left to right it sees "cgc" then the next character is a "g" so that character is skipped. So the next occurence happens on the next "cgc". As you can see this only happens 3 times. Now you can get 6 if after the first "cgc" you back up a character.
chris at pecoraro dot net
27-Mar-2003 01:24
this function also doesn't work well if you have "cgcgcgcgcgcgcg" as a search string and you want to count occurences of "cgc"
it returns "3", whereas it SHOULD return "6", assuming we allow "overlapping". Maybe there should be an "allow overlap" optional parameter.
-cjp
bpotter at statelinecasinos dot com
07-Sep-2002 08:11
This is useful for pages that depend on the QUERY_STRING for values. Some search Engines (AOL) use & in the link, which can cause problems and/or wrong information to be displayed.
if (substr_count($QUERY_STRING, "amp;") > 0) {
$QUERY_STRING = str_replace("amp;", "", $QUERY_STRING);
$queryArray = explode("&",$QUERY_STRING);
foreach ($queryArray as $queryItem) {
$querySegment = explode("=",$queryItem);
list ($key, $val) = $querySegment ;
if ($val)
$$key = $val;
}
}
Hope this helps.
Jesse at bend dot com
08-Jan-2001 09:58
I am not certain why the above fellah is worried about case sensitivity, ereg functions are mighty slow.. and if you need a case insensitive count, try this:
substr_count(strtolower($haystack), strtolower($needle))
| |