获取几个string中最常用的两个单词

我有一个短语列表,我想知道在我所有的短语中最常出现哪两个词。

我试图玩正则expression式和其他代码,我只是找不到正确的方法来做到这一点。

谁能帮忙?

例如:

I am purchasing a wallet a wallet for 20$ purchasing a bag 

我知道

  • a wallet发生了2次
  • purchasing a发生了2次

 <? $string = "I am purchasing a wallet a wallet for 20$ purchasing a bag"; //split string into words $words = explode(' ', $string); //make chunks block ie [0,1][2,3]... $chunks = array_chunk($words, 2); //remove first array element unset($words[0]); //make chunks block ie [0,1][2,3]... //but since first element is removed , the real block will be [1,2][3,4]... $alternateChunks = array_chunk($words, 2); //merge both chunks $totalChunks = array_merge($chunks,$alternateChunks); $finalChunks = array(); foreach($totalChunks as $t) { //change the inside chunk to pharse using + //+ can be replaced to space, if neeced //to keep associative working + is used instead of white space $finalChunks[] = implode('+', $t); } //count the words inside array $result = array_count_values($finalChunks); echo "<pre>"; print_r($result); 

我毫不犹豫地提出这个build议,因为这是一个非常暴力的方式去做:

把你的string,爆炸爆炸(“”,$string); 命令,然后通过for循环检查每两个字组合对string中的每两个字。

 $string = "I am purchasing a wallet a wallet for 20$ purchasing a bag"; $words = explode(" ", $string); for ($t=0; $t<count($string); $t++) { for ($i=0; $i<count($string); $i++) { if (($words[$t] . words[$t+1]) == ($words[$i] . $word[$i+1])) {$count[$words[$i].$words[$i+1]]++} } } 

因此,嵌套for循环步骤,抓住前两个单词,比较他们对彼此连续两个单词的集合,然后抓住接下来的两个单词,再次做。 每个答案将有一个至less1的答案(它总是会自己匹配),但按大小sorting产生的数组将会给你最重复的值。

请注意,这将运行(n-1)*(n-1)次迭代,这可能难以实现FAST。

将它们全部放入一个数组中,并通过当前词索引和下一个词索引来访问它们。

我认为这应该做的伎俩。 它会抓住一对单词,除非你是在string的末尾,在那里你只会得到一个单词。

 $str = "I purchased a wallet because I wanted a wallet a wallet a wallet"; $words = explode(" ", $str); $array_results = array(); for ($i = 0; $i<count($words); $i++) { if ($i < count($words)-1) { $pair = $words[$i] . " " . $words[$i+1]; echo $pair . "\n"; // Have to check if the key is in use yet to avoid a notice $array_results[$pair] = isset($array_results[$pair]) ? $array_results[$pair] + 1 : 1; } // At the end of the array, just use a single word else $array_results[$words[$i]] = isset($array_results[$words[$i]]) ? $array_results[$words[$i]] + 1 : 1; } // Sort the results // use arsort() instead to get the highest first asort($array_results); // Prints: Array ( [I wanted] => 1 [wanted a] => 1 [wallet] => 1 [because I] => 1 [wallet because] => 1 [I purchased] => 1 [purchased a] => 1 [wallet a] => 2 [a wallet] => 4 ) 

更新 ++更改为+1以上,因为它testing时不工作…

尝试将其与爆炸放入一个数组,并用array_count_values计数值。

 <?php $text = "whatever"; $text_array = explode( ' ', $text); $double_words = array(); for($c = 1; $c < count($text_array); $c++) { $double_words[] = $text_array[$c -1] . ' ' . $text_array[$c]; } $result = array_count_values($double_words); ?> 

我现在更新到两个字的版本。 这对你有用吗?

 array(9) { ["I am"]=> int(1) ["am purchasing"]=> int(1) ["purchasing a"]=> int(2) ["a wallet"]=> int(2) ["wallet a"]=> int(1) ["wallet for"]=> int(1) ["for 20$"]=> int(1) ["20$ purchasing"]=> int(1) ["a bag"]=> int(1) } 

既然你使用了excel标签,我想我会试试看,其实很简单。

  1. 分隔string使用空格作为分隔符。 数据>文本到列…>分隔符>分隔符:空格。 每个单词现在都在自己的单元格中。
  2. 调换结果(不是严格要求,但更容易可视化)。 复制,编辑>select性粘贴…>移调。
  3. 使单元格包含连续的单词对。 所以如果你的单词在单元格B5:B15中,单元格C5应该是=B5&" "&B6 (并向下拖动)。
  4. 计算每个单词对的出现次数:在单元格D5中, =COUNTIF($C$5:$C$15,"="&C5) ,向下拖动。
  5. 突出显示赢家(S)。 selectC5:D15,格式>条件格式…>公式是=$D5=MAX($D$5:$D$15)并select例如黄色背景。

请注意,步骤4中存在一些低效率,因为如果该字对出现多次,则每个字对的计数将被多次计算。 如果这是一个问题,那么您可以首先使用数据>filter>高级filter…>唯一logging来制作唯一的单词对列表。

一个自动化的VBA解决scheme可以很容易地通过logging上面的一个macros,然后进行一些小的编辑来制作。

其中一种方法是使用SPLIT或正则expression式将句子拆分为单词并将其存储到数组中。 然后采取数组并创build一个字典对象。 当您向字典中添加一个字词时,如果字典已经存在,请将.value加1以统计字数。

下面是一些示例代码(远非完美,因为它只是显示重叠的概念),它将采用列A中的所有string,并在B和C列中生成一个字频列表。这不完全是你想要的,但应该给你关于如何去做的一些想法我希望:

 Sub FrequencyList() Dim vArray As Variant Dim myDict As Variant Set myDict = CreateObject("Scripting.Dictionary") Dim i As Long Dim cell As range With myDict For Each cell In range("A1", cells(Rows.count, "A").End(xlUp)) vArray = Split(cell.Value, " ") For i = LBound(vArray) To UBound(vArray) If Not .exists(vArray(i)) Then .Add vArray(i), 1 Else .Item(vArray(i)) = .Item(vArray(i)) + 1 End If Next Next range("B1").Resize(.count).Value = Application.Transpose(.keys) range("C1").Resize(.count).Value = Application.Transpose(.items) End With End Sub