Estoy tratando de hacer una función, que detectará cuántas veces, diferentes palabras ocurrieron en un texto. La cuestión es que me gustaría agrupar palabras similares (y apodos).

Tengo este conjunto de palabras interesantes (que he definido manualmente):

$interesting_words = [
  'test' => [
    'number_of_occurances' => 0,
    'connected_words' => [
        'TEST',
        'TESTER',
        'TESTING'
      ]
    ],
  'foobar' => [
    'number_of_occurances' => 0,
    'connected_words' => [
        'FOO',
        'FOOBAR',
        'BAR'
      ]
    ]
]

Texto de ejemplo.

PRUEBA Lorem ipsum sentarse amet, consectetur TESTER elit. Sed en turpis dui. Maecenas venenatis FOOBAR facilisis. Dictamen de quisque, prueba de diam consequat mollis, orci tellus aliquet nisl, BAR molestie FOO augue at est. En PRUEBA vehicula lectus. Curabitur ac varius ligula. Pellentesque orci urdna.

Salida deseada.

Number of occurances for 'test': 4
Number of occurances for 'foobar': 3

¿Hay una manera inteligente de hacer esto sin tener 1,000,000 de bucles for?

Estoy haciendo la función en Laravel, si eso es de ayuda.

3
Zeth 8 sep. 2018 a las 12:24

3 respuestas

La mejor respuesta

Puede usar str_word_count && array_count_values, para obtener todas las apariciones de palabras y strtolower para hacer que la búsqueda no sea sensible a mayúsculas y minúsculas cuando el rendimiento y solo el número de ocurrencias cuentan:

$words=array_count_values(str_word_count(strtolower($str),1));
foreach($interesting_words as $index=>&$details){
    foreach($details['connected_words'] as $key=>$similar){
        $details['number_of_occurances'] += $words[strtolower($similar)];
    }
}           
print_r($interesting_words );

Salida:

Array
(
    [test] => Array
        (
            [number_of_occurances] => 4
            [connected_words] => Array
                (
                    [0] => TEST
                    [1] => TESTER
                    [2] => TESTING
                )

        )

    [foobar] => Array
        (
            [number_of_occurances] => 3
            [connected_words] => Array
                (
                    [0] => FOO
                    [1] => FOOBAR
                    [2] => BAR
                )

        )

)
1
Elementary 8 sep. 2018 a las 13:16
<?php


$interesting_words = [
  'test' => [
    'number_of_occurances' => 0,
    'connected_words' => [
        'TEST',
        'TESTER',
        'TESTING'
      ]
    ],
  'foobar' => [
    'number_of_occurances' => 0,
    'connected_words' => [
        'FOO',
        'FOOBAR',
        'BAR'
      ]
    ]
];

$testCount=$interesting_words['test']['number_of_occurances'];
$foobarCount=$interesting_words['foobar']['number_of_occurances'];

$text="Lorem ipsum TEST sit amet, consectetur TESTER elit. Sed in turpis dui. Maecenas venenatis 
FOOBAR facilisis. Quisque dictum, diam consequat mollis TESTING, orci tellus aliquet nisl, BAR 
molestie FOO augue at est. In TESTING vehicula lectus. Curabitur ac varius ligula. 
Pellentesque orci urdna.";

$arr= explode(" ", $text);
$numberOfWords=count($arr);
for($i=0;$i<$numberOfWords;$i++)
{
    echo "<br/>";

    if(strpos($arr[$i],'TEST') !== false){
        $testCount=$testCount+1;
    }

    elseif(strpos($arr[$i],'TESTER') !== false){          

    $testCount=$testCount+1;
    }
    elseif(strpos($arr[$i],'TESTING') !== false){

    $testCount=$testCount+1;
    } 

   elseif(strpos($arr[$i],'FOO') !== false){

    $foobarCount=$foobarCount+1;
    }  

   elseif(strpos($arr[$i],'FOOBAR') !== false){

    $foobarCount=$foobarCount+1;
    } 

   elseif(strpos($arr[$i],'BAR') !== false){ 

    $foobarCount=$foobarCount+1;
    }   
}
echo "Number of occurances for 'test':".$testCount;
echo "</br>";
echo "Number of occurances for 'foobar':".$foobarCount;
0
cool_benn 8 sep. 2018 a las 10:32

Creo que se puede hacer con explode y array_count_values y para que funcione En el siguiente ejemplo, eliminé . y ,

<?php
$interesting_words = [
  'test' => [
    'number_of_occurances' => 0,
    'connected_words' => [
        'TEST',
        'TESTER',
        'TESTING'
      ]
    ],
  'foobar' => [
    'number_of_occurances' => 0,
    'connected_words' => [
        'FOO',
        'FOOBAR',
        'BAR'
      ]
    ]
];
$str = 'Lorem ipsum TEST sit amet, consectetur TESTER elit. Sed in turpis dui. Maecenas venenatis FOOBAR facilisis. Quisque dictum, diam consequat mollis TESTING, orci tellus aliquet nisl, BAR molestie FOO augue at est. In TESTING vehicula lectus. Curabitur ac varius ligula. Pellentesque orci urdna.';
$str = preg_replace('/[\.\,]/i','',$str);
$str = strtolower($str);
$str_arr = explode(" ",$str);
$str_occurance_counts = array_count_values($str_arr);
foreach($interesting_words as $k=>&$v){
  foreach($v['connected_words'] as $c=>$cVal){
    $v['number_of_occurances'] += $str_occurance_counts[strtolower($cVal)];
  }
}
print_r($interesting_words );
?>

Live Demo Server1

Live Demo Server2

0
Niklesh Raut 8 sep. 2018 a las 10:21