2011-01-19 11 views
5

Digamos que tengo dos cadenas.Cuenta de PHP de ocurrencias de caracteres de una cadena dentro de otra cadena

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

Quiero contar la frecuencia con personajes que se encuentran en $needle se producen en $haystack. En $haystack, están los caracteres 'A' (dos veces), 'X', 'Y' y 'Z', todos ellos en la aguja, por lo que se supone que el resultado es 5 (distingue entre mayúsculas y minúsculas).

¿Hay alguna función para eso en PHP o tengo que programarla yo mismo?

¡Gracias de antemano!

Respuesta

18

Puede calcular la longitud de la cadena original y la longitud de la cadena sin estos caracteres. Las diferencias entre ellos es el número de coincidencias.

Básicamente,

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

Aquí es la parte que hace el trabajo. En una linea

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

Explicación: La primera parte es auto-explicativo. La segunda parte es la longitud de la cadena sin los caracteres en la cadena $needle.Esto se hace reemplazando cada ocurrencia de cualquier carácter dentro del $needle con una cadena en blanco.

Para hacer esto, dividimos $needle en una matriz, una vez caracteres para cada elemento, usando str_split. Luego, pásalo al str_replace. Reemplaza cada aparición de cualquier elemento en la matriz $search con una cadena en blanco.

Echo un vistazo,

echo "Count = $count\n"; 

que se obtiene:

Count = 5

+4

+1, nice out-of-the-box ¡pensando! – acm

3

No hay ningún método específico para hacer esto, pero esta construida en el método sin duda le puede ayudar:

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

edición: me acaba de informar el substr_count generales method..in su caso en particular lo que necesita llamarlo para cada personaje dentro de la aguja $ (gracias @Alan Whitelaw)

+2

Esto sólo buscará 'AGUXYZ' en el pajar como php.net/substr-count muestra' $ needle' a ser una cadena –

+0

Esto es el ejemplo genérico de la substr_count ... para lograr ese resultado en particular, debe verificar cada carácter de la cadena $ needle :) ..sorry No lo he explicado;) – stecb

4

no hay ninguna función integrada que se encarga de juegos de caracteres, pero sólo tiene que utilizar la función substr_count en un bucle como tal:

<?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); 
?> 
0

substr_count lo acercarán. Sin embargo, no hará caracteres individuales. De modo que podría recorrer cada carácter en $needle y llamar a esta función mientras se suman los recuentos.

6

Pruebe esto;

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; 
} 

Para usar;

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

puede establecer el tercer parámetro a false ignorar caso.

0

Hay una función PHP substr_count para contar el número de instancias de un carácter en una cadena. Sería trivial para extenderlo por varios personajes:

0

voy a hacer algo como: dividir la cadena de caracteres (str_split), y luego usar array_count_values, para obtener variedad de todos los personajes, ¿cuántas veces es ocurrir.

$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"; 
1

Si usted no está interesado en la distribución de caracteres, se puede usar una expresión regular

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

que devuelve el número de coincidencias de patrón completo (que podría ser cero) o FALSE si se produce un error. El solution offered by @thai anterior debería ser significativamente más rápido.


Si la distribución de caracteres es de alguna importancia, puede utilizar 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)) 
    ) 
); 

El resultado sería una matriz con teclas siendo los valores ASCII del carácter.
entonces usted puede iterar sobre ella con

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

Aún se podía pasar la matriz a $occurencesarray_sum para calcular el total.

+1

Bueno, eso es el equivalente de lo que acabo de publicar, así que +1 a usted señor ... – ircmaxell

+0

@ircmaxell lo siento :) y gracias – Gordon

+1

usted sabe lo que dicen, * Las mentes geniales piensan igual, pero los tontos rara vez difieren * ... – ircmaxell

0

Tengo un método recursivo para superar esto:

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 
Cuestiones relacionadas