6

Let's say I have two strings.

$needle = 'AGUXYZ';
$haystack = 'Agriculture ID XYZ-A';

I want to count how often characters that are in $needle occur in $haystack. In $haystack, there are the characters 'A' (twice), 'X', 'Y' and 'Z', all of which are in the needle, thus the result is supposed to be 5 (case-sensitive).

Is there any function for that in PHP or do I have to program it myself?

Thanks in advance!

9 Answers 9

22

You can calculate the length of the original string and the length of the string without these characters. The differences between them is the number of matches.

Basically,

$needle = 'AGUXYZ';
$haystack = 'Agriculture ID XYZ-A';

Here is the part that does the work. In one line.

$count = strlen($haystack) - strlen(str_replace(str_split($needle), '', $haystack));

Explanation: The first part is self-explanatory. The second part is the length of the string without the characters in the $needle string. This is done by replacing each occurrences of any characters inside the $needle with a blank string.

To do this, we split $needle into an array, once character for each item, using str_split. Then pass it to str_replace. It replaces each occurence of any items in the $search array with a blank string.

Echo it out,

echo "Count = $count\n";

you get:

Count = 5

Sign up to request clarification or add additional context in comments.

Comments

6

Try this;

function count_occurences($char_string, $haystack, $case_sensitive = true){
    if($case_sensitive === false){
        $char_string = strtolower($char_string);
        $haystack = strtolower($haystack);
    }

    $characters = str_split($char_string);
    $character_count = 0;
    foreach($characters as $character){
        $character_count = $character_count + substr_count($haystack, $character);
    }
    return $character_count;
}

To use;

$needle = 'AGUXYZ';
$haystack = 'Agriculture ID XYZ-A';
print count_occurences($needle, $haystack);

You can set the third parameter to false to ignore case.

Comments

4

There's no built-in function that handles character sets, but you simply use the substr_count function in a loop as such:

<?php
    $sourceCharacters = str_split('AGUXYZ');
    $targetString = 'Agriculture ID XYZ-A';
    $occurrenceCount = array();

    foreach($sourceCharacters as $currentCharacter) {
        $occurrenceCount[$currentCharacter] = substr_count($targetString, $currentCharacter);
    }

    print_r($occurrenceCount);
?>

Comments

3

There is no specific method to do this, but this built in method can surely help you:

$count = substr_count($haystack , $needle);

edit: I just reported the general substr_count method..in your particular case you need to call it for each character inside $needle (thanks @Alan Whitelaw)

2 Comments

This will only look for AGUXYZ in the haystack as php.net/substr-count shows $needle to be a string
This is the generic example of the substr_count... to achieve that particular result you need to check every char of the $needle string :) ..sorry I didn't explained it ;)
1

If you are not interested in the character distribution, you could use a Regex

echo preg_match_all("/[$needle]/", $haystack, $matches);

which returns the number of full pattern matches (which might be zero), or FALSE if an error occurred. The solution offered by @thai above should be significantly faster though.


If the character distribution is of any importance, you can use count_chars:

$needle = 'AGUXYZ';
$haystack = 'Agriculture ID XYZ-A';

$occurences = array_intersect_key(
    count_chars($haystack, 1),
    array_flip(
        array_map('ord', str_split($needle))
    )
);

The result would be an array with keys being the ASCII values of the character.
You can then iterate over it with

foreach($occurences as $char => $amount) {
    printf("There is %d occurences of %s\n", $amount, chr($char));
}

You could still pass the $occurences array to array_sum to calculate the total.

1 Comment

$matches doesn't need to be declared in the first snippet.
0

substr_count will get you close. However, it will not do individual characters. So you could loop over each character in $needle and call this function while summing the counts.

Comments

0

There is a PHP function substr_count to count the number of instances of a character in a string. It would be trivial to extend it for multiple characters:

function substr_multi_count ($haystack, $needle, $offset = 0, $length = null) {
    $ret = 0;

    if ($length === null) {
        $length = strlen($haystack) - $offset;
    }

    for ($i = strlen($needle); $i--; ) {
        $ret += substr_count($haystack, $needle, $offset, $length);
    }

    return $ret;
}

Comments

0

I have a recursive method to overcome this:

function countChar($str){

  if(strlen($str) == 0) return 0;

  if(substr($str,-1) == "x") return 1 + countChar(substr($str,0,-1));

  return 0 + countChar(substr($str,0,-1));

}

  echo countChar("xxSR"); // 2
  echo countChar("SR"); // 0
  echo countChar("xrxrpxxx"); // 5

1 Comment

This answer does not provide the required process. This checks for a statically declared string.
0

I'd do something like:

  1. split the string to chars (str_split), and then
  2. use array_count_values to get an array of characters with the respective number of occurrences.

Code:

$needle = 'AGUXYZ';
$string = "asdasdadas asdadas asd asdsd";
$array_chars = str_split($string);
$value_count = array_count_values($array_chars);
for ($i = 0; $i < count($needle); $i++)
    echo $needle[$i]. " is occur " . 
         ($value_count[$needle[$i]] ? $value_count[$needle[$i]] : '0')." times";

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.