2017-09-22 99 views
5

我有一個計劃,以使從txt文件的搜索,我準備,類似這樣的txt文件內容如下PHP搜索數組多個關鍵字和排序結果

A.TXT

Amy Jefferson 
Nathalie Johnson 
Emma West 
Donna Jefferson 
Tanya Nathalie 
George West 
Emma Watson 
Emma Jefferson 

如果代碼是這樣

a.php只會

$filename = "a.txt"; 
$example = file($filename, FILE_IGNORE_NEW_LINES); 
$searchword = 'Emma Jefferson'; 
$matches = array(); 
foreach($example as $k=>$v) { 
    if(preg_match("/\b$searchword\b/i", $v)) { 
     $matches[$k] = $v; 
     echo $matches[$k]."<br>"; 
    } 
} 

結果只會 「艾瑪·傑斐遜」

然後,如果我使用此代碼

b.php

$filename = "a.txt"; 
$example = file($filename, FILE_IGNORE_NEW_LINES); 
$searchword = 'Emma Jefferson'; 
$matches = array(); 
foreach($example as $k=>$v) { 
    $searchword2 = str_ireplace(" ", "|", $searchword); 
    if(preg_match("/\b$searchword2\b/i", $v)) { 
     $matches[$k] = $v; 
     echo $matches[$k]."<br>"; 
    } 
} 

結果會是這樣

Amy Jefferson 
Emma West 
Donna Jefferson 
Emma Watson 
Emma Jefferson 

獨特的結果,但 「艾瑪·傑斐遜」 在最後的結果

所以問題是我如何搜索艾瑪傑斐遜,結果排序是這樣的

Emma Jefferson 
Emma Watson 
Emma West 
Amy Jefferson 
Donna Jefferson 

所以基本上是搜索「艾瑪·傑斐遜」整個單詞,然後再「艾瑪」,最後一個是「傑斐遜」

UPDATE 我投做這個驚慌代碼問題,但我想說在這裏感謝你的所有貢獻者不要驚慌,RomanPerekhrest,隋夢,傑爾,我的人,你們都是最棒的!

Pattygeek

回答

1

我不知道的方式來採取比賽的位置考慮用正則表達式解決方案,但如果轉換搜索字符串和條款可以完成單詞數組。

使用這種方法,我們迭代文本項目併爲搜索詞中的每個單詞構建一個位置匹配數組,然後按結果匹配數和匹配位置對結果進行排序。

$search_words = explode(' ', strtolower($searchword)); 

foreach ($example as $item) { 
    $item_words = explode(' ', strtolower($item)); 

    // look for each word in the search term 
    foreach ($search_words as $i => $word) { 
     if (in_array($word, $item_words)) { 

      // add the index of the word in the search term to the result 
      // this way, words appearing earlier in the search term get higher priority 
      $result[$item][] = $i; 
     } 
    } 
} 

// this will sort alphabetically if the uasort callback returns 0 (equal) 
ksort($result); 

// sort by number of matches, then position of matches  
uasort($result, function($a, $b) { 
    return count($b) - count($a) ?: $a <=> $b; 
}); 

// convert keys to values  
$result = array_keys($result); 
+0

嗨不要恐慌,謝謝你的迴應:)但我仍然得到那種不像我想要的,這就是我得到的艾瑪傑佛遜艾瑪沃森唐娜傑佛遜艾瑪西艾米傑弗遜,同時我想就在列表上的結果我上面寫過 – pattygeek

+0

啊,我明白了,所以這不僅僅是比賽的數量,還是比賽的順序呢? –

+0

是的:D那部分有點讓我困惑:D – pattygeek

0

您當前回顯結果,所以它們按照文本排序。

您可以搜索完整的字符串和部分匹配,然後concatenate results

foreach($example as $k=>$v) { 
    if(preg_match("/\b$searchword\b/i", $v)) { 
     $fullMatches[] = $v; 
    } 
    if(preg_match("/\b$searchword2\b/i", $v)) { 
     $matches[] = $v; 
    } 
} 
$matches = array_unique(array_merge($fullMatches, $matches)); 
foreach($matches as $k => $v) 
    echo $v . "<br>"; 

更新:

多個詞的變體:

$words = ['Emma', 'Jefferson']; 
$matches = array(); 
foreach($example as $k => $v) { 
    $fullStr = implode(' ', $words); 
    if(preg_match("/\b$fullStr\b/i", $v)) 
     $matches[0][] = $v; 
    $str = ""; 
    $i = 1; 
    foreach($words as $word) { 
     if ($str === "") 
      $str = $word; 
     else 
      $str .= '|' . $word; 
     if(preg_match("/\b$str\b/i", $v)) 
      $matches[$i][] = $v; 
     $i++; 
    } 
} 
$result = array(); 
foreach($matches as $firstKey => $arr) { 
    foreach($arr as $secondKey => $v) { 
     $result[] = $v; 
    } 
} 
$result = array_unique($result); 
foreach($result as $k => $v) 
    echo $v . "<br>"; 
+0

感謝隋因爲我想要的迴應:),其艾瑪 - 傑弗森在上面工作,但其餘的還是不喜歡,代碼的結果你把它給我的是這樣的 艾瑪·傑斐遜 艾米傑斐遜 艾瑪西 唐娜·傑斐遜 艾瑪·沃特森 同時,結果,我想這樣的一個 艾瑪·傑斐遜 艾瑪·沃特森 艾瑪西 艾米傑斐遜 唐娜·傑斐遜 – pattygeek

+0

是否有可能使它的動態,我的意思是搜索可以是任何字不僅2 – pattygeek

+0

對不起隋,但爲什麼當我嘗試你的代碼時,a.txt上的所有數據都顯示? – pattygeek

0

絡合物溶液:

$lines = file('a.txt', FILE_IGNORE_NEW_LINES); 
$name = 'Emma'; 
$surname = 'Jefferson'; 
$emmas = $jeffersons = []; 

foreach ($lines as $l) { 
    if (strpos($l, $name) === 0) { 
     $emmas[] = $l; 
    } elseif (strrpos($l, $surname) === (strlen($l) - strlen($surname))) { 
     $jeffersons[] = $l; 
    } 
} 

usort($emmas, function($a,$b){ 
    return strcmp(explode(' ', $a)[1], explode(' ', $b)[1]); 
}); 
usort($jeffersons, function($a,$b){ 
    return strcmp($a, $b); 
}); 

$result = array_merge($emmas, $jeffersons); 
print_r($result); 

輸出:

Array 
(
    [0] => Emma Jefferson 
    [1] => Emma Watson 
    [2] => Emma West 
    [3] => Amy Jefferson 
    [4] => Donna Jefferson 
) 
+0

嗨Roman,謝謝你的迴應:)結果就像我想要的,但問題是,是否有可能使$ name和$ surname是動態的,因爲在這裏搜索可以超過2個單詞 – pattygeek

+0

@pattygeek,如果*搜索可以超過2個單詞* - 你將如何排序4或更多單詞分開嗎?這對你來說將是非常困難的情況。我的解決方案解決了當前問題 – RomanPerekhrest

0

你將不得不編寫一個新的循環或開始排序你的數組後綴,因爲foreach循環在當時接受一個元素名稱,測試它是否與你的搜索詞相匹配,如果它符合,名字在末尾您的新陣列$matches[]。所以

if(preg_match("/\b$searchword2\b/i", $v)) { 
    $matches[$k] = $v; 
    echo $matches[$k]."<br>"; 
} 

部分不知道是或不是已經是$matches[]裏面的名字什麼。

所以我的建議是:

$filename = "a.txt"; 
$example = file($filename, FILE_IGNORE_NEW_LINES); 
$searchword = 'Emma Jefferson'; 
$matches = array(); 



$searchword2 = array($searchword, explode(" ", $searchword)[0], explode(" ", $searchword)[1]); 
$isThisNameAlreadyInTheList; 

foreach($searchword2 as $actualSearchword) { 

    foreach($example as $k=>$v) { 

     $isThisNameAlreadyInTheList = false; 
     foreach($matches as $match) { 
      if(preg_match("/\b$match\b/i", $v)) { 
       $isThisNameAlreadyInTheList = true; 
      } 
     } 

     if (!$isThisNameAlreadyInTheList) { 
      if(preg_match("/\b$actualSearchword\b/i", $v)) { 
       $matches[$k] = $v; 
       echo $matches[$k]."<br>"; 
      } 
     } 
    } 

} 
+0

感謝Jere對這部分的迴應:) $ searchword2 = array(「Emma Jefferson」,「Emma」,「Jefferson」);它可以使動態,我嘗試$ searchword2 = explode(「|」,$ searchword);但仍然混淆在哪裏把「艾瑪傑斐遜」 – pattygeek

+0

這是我上傳代碼時犯的一個錯誤。它現在應該是正確的。 – Jere

+0

對不起,遲到了,Jere的工作!但如果結果如何超過2個字?可以在不編輯$ searchword2的情況下進行搜索? – pattygeek

0

我會用一個preg_match_all的解決方案,像這樣:

$searchName = "Emma Jefferson"; 
$searchTerms = explode(' ', $searchName); 

$pattern = "/(\b$searchTerms[0]\b \b$searchTerms[1]\b)|(\b$searchTerms[0]\b \w+)|(\w* \b$searchTerms[1]\b)/i"; 

$output = []; 
preg_match_all($pattern, implode(' | ', $example), $out); 

foreach($out as $k => $o){ 
    if($k == 0){ 
     continue; 
    } 

    foreach($o as $item){ 
     if(!empty($item)){ 
      $output[] = $item; 
     } 
    } 
} 

print_r($output); 

你也可以將文件作爲一個字符串,避免了內爆部分。

+0

嗨我的人感謝迴應:)結果就像我想要的一樣!但模式部分,我如何使它動態?謝謝 – pattygeek

+0

我更新了我的答案,使搜索字詞在名稱之間的空格更加動態分割 –

+0

對不起,對於遲到的回覆,i-man如果搜索超過2個單詞怎麼辦?它還在工作嗎? – pattygeek