2016-05-24 32 views
1

因此,對於我的大學畢業論文,我選擇構建一個Web應用程序,從文章(摘要應用程序)中提取主要想法。它建立在PHP中。從基於缺少某些單詞的另一個句子的文本中提取句子

但是,我已經達到了一個我看不到任何可能的解決方案的情況,也許你們可以給我一個想法或問題的解決方案。

所以基本上應用程序依賴於提取算法,我做的是: 首先,我「清理」文本,這意味着我刪除所有停用詞,我幹掉這些詞,刪除任何可能包含' 「。這可以改變我的文本不會被正確地分解成句子。 之後,我通過.令牌爆炸文本將文本分解爲句子,並獲取數組中的所有句子。 現在是我給予句子評分的過程,基本上這就是我如何發現文章中最相關的句子,評分最高的句子通常是包含文章主要思想的句子。

但是我現在的問題從現在開始,我評價的句子就是我應用了所有「消毒」的句子,而且都不是原來的格式。我想拿最高評分的句子,並根據這一點我想從該評級句子匹配的文本中提取原始句子。我試圖將它與正則表達式匹配,但它並不總是工作。我需要一個100%的工作方法,根據評分最高的句子從文章中提取原文。

我不知道如何實現這一點,因爲額定的句子漏掉了它的單詞。 我希望你明白我的觀點。謝謝。

編輯: 這是我現在用文章的匹配原句的功能,但我並不總是奏效:

private function get_original_sentence($s, $t) 
    { 
     $s = preg_replace("/[^A-Za-z0-9 ]/", '', $s); 
     $s = trim($s); 

     $arr = explode(" ",$s); 
     $f_word = $arr[0]; 
     $l_word = $arr[count($arr)-1]; 

     preg_match('~(?<=\.)([a-zA-Z ]*)'.$f_word.'(.*?)'.$l_word.'([a-zA-Z ]*)(?=\.)~i', $t, $matches); 

     if(empty($string)) 
     { 
      preg_match('~(?<=\.)([^\.]*)'.$f_word.'(.*?)'.$l_word.'([^\.]*)(?=\.)~i', $t, $matches); 
     } 

     return $matches[0] ? $matches[0] : false; 
    } 

$s參數是總結和$t之後額定句子是完整的原創文章。編輯2:縮寫刪除功能,它實際上消毒整個文本,不僅僅是縮寫。

static private function _remove_abbrev($subject) 
    { 
     $domains = '\.ro|\.com|\.edu|\.org|\.gov'; 

     foreach(self::$abrv as $abrv) 
     { 
      $not.= strtolower(str_replace('.', '\.', $abrv)).'|'; 
      $not.= strtolower(trim(str_replace('.', '\.', $arbv))).'|'; 
     } 

     $not = substr($not, 0, -1); 

     //$subject = preg_replace('~(\".*?\")~u', '', strtolower($subject));//replaces " " from text. 
     $subject = preg_replace('~(?<=\.|^)(?![^\.]{60,})[^\.&]*\&[^\.]*\.?~u', '', strtolower($subject)); 
     $subject = preg_replace('~\b\s?[\dA-za-z\-\.]+('.$domains.')~u', '', strtolower($subject)); 
     $subject = preg_replace('~\s*\(.*?\)\s*~u', '', strtolower($subject)); 
     $subject = preg_replace('~\b('.$not.')~u', '', strtolower($subject)); 
     $subject = preg_replace('~(?<=[^a-z])[A-Za-z]{1,5}+\.[\s\,]*(?=[a-z]|[0-9])~u', '', strtolower($subject)); 
     $subject = preg_replace('~(?<=[\s\,\.\:])([A-Za-z]*(\.)){2,}+(.)(?=.*)~u', '', strtolower($subject)); 
     $subject = preg_replace('~(\d)+\.(\d)*(\s)~u', '', strtolower($subject)); 

     return $subject; 
    } 

這是縮寫數組集合:

static public $abrv = array(
     ' alin.', ' art.', ' A.N.P', ' A.V.A.B', ' A.V.A.S.', ' B.N.R', ' c.', ' C.A.S', ' C.civ.', ' C.com.', ' C.fam.', ' C.pen.', ' C.pr.civ.', ' C.pr.pen', ' C.N.C.D', ' C.N.V.M', ' C.N.S.A.S', ' C.S.M', ' C.S.J', ' D.G.F.P', ' D.G.P.M.B', ' D.N.A', ' D.S.V', 'Ed.', ' etc.', ' H.G.', ' I.G.P.F', ' I.G.P.R', ' I.N.M.L.', ' I.P.J', ' I.C.C.J', ' lit.', ' M.Ap.N.', ' art.', ' M.J.', ' M.Of.', ' nr.', ' O.G.', ' O.U.G.', ' p.', ' P.N.A.', ' par.', ' pct.', ' R.A.A.P.P.S.', ' subl. ns.', ' S.C.', ' S.A.', ' S.P.P.', ' S.R.I.', ' S.R.L.', 'U.N.B.R.', ' urm.', ' str.', ' sec.', ' pag.', ' a.c.', ' dv.', ' dvs.', ' prof.', ' conf.', ' dr.', ' drd.', ' mrd.', ' s.a.m.d' 
    ); 
+0

@FrayneKonok編輯的代碼的答案。 – southpaw93

+0

是的,我明白了,現在人們可以幫助你。 –

+0

我想你應該分配句子獨特的ID – noreabu

回答

0

如何對這種做法:

  1. 你提取所有與preg_match_all比賽第一與數值指標$替代
  2. 數組
  3. 然後用一個獨特的標記替換它們,利用preg_replace的4個變量:$ count,它的值指向$ substit utions陣列

粗略的草圖代碼:

$count = 0; 
$substitutions = array(); 
foreach ($patterns as $pattern) { 
    $matches = array(); 
    preg_match_all($pattern, $subject, $matches); 
    preg_replace($pattern, $subject, '__'.$count.'__', -1, $count); 

    foreach ($matches[???] as $match) { 
     $substiutions[] = $match; 
    } 
} 

我不知道如果我搞砸了用於參考$語法算作引用調用(如文檔中的& $)。

我認爲這種方法的癥結在於從$ matches數組中提取正確的值。有一些選項,如何提取匹配。也許另一種方法可能不是使用來自preg_replace的$ count,而是從$匹配的相應子數組中使用$ count

0

_remove_abbr函數似乎不能很好地工作。它在句子結尾處刪除諸如「藝術」之類的詞,但不刪除諸如「C.A.S.」之類的縮寫。 (因爲它已經刪除了「c」)。它還至少有一個拼寫錯誤($arbv),並且在連接到它之前沒有定義$not

不過,如果不是刪除縮寫,URL等,而是用空格字符替換它們呢?這樣,當你將文本分割成句子時,它們的長度仍然與原始文本的長度相同,因此你可以存儲句子開始和結束的位置。如有必要,您可以在此處將多個空格轉換爲單個空格,但您仍然可以知道它們來自何處。

你只需要一個回調函數來實現這一目標:

$f = function($m){ return str_repeat(" ", strlen($m[0])); }; 
    $subject = preg_replace_callback('~(?<=\.|^)(?![^\.]{60,})[^\.&]*\&[^\.]*\.?~u', $f, strtolower($subject)); 
    $subject = preg_replace_callback('~\b\s?[\dA-za-z\-\.]+('.$domains.')~u', $f, $subject); 
    $subject = preg_replace_callback('~\s*\(.*?\)\s*~u', $f, $subject); 
    $subject = preg_replace_callback('~\b('.$not.')~u', $f, $subject); 
    $subject = preg_replace_callback('~(?<=[^a-z])[A-Za-z]{1,5}+\.[\s\,]*(?=[a-z]|[0-9])~u', $f, $subject); 
    $subject = preg_replace_callback('~(?<=[\s\,\.\:])([A-Za-z]*(\.)){2,}+(.)(?=.*)~u', $f, $subject); 
    $subject = preg_replace_callback('~(\d)+\.(\d)*(\s)~u', $f, $subject);