Computer >> Máy Tính >  >> Lập trình >> PHP

Chia chuỗi thành các câu bằng cách sử dụng regex trong PHP

Ví dụ

function sentence_split($text) {
   $before_regexes =
      array('/(?:(?:[\'\"„][\.!?…][\'\"”]\s)|(?:[^\.]\s[A-Z]\.\s)|(?:\b(?:St|Gen|Hon|Prof|Dr|Mr|Ms|Mrs|[JS]r|Col|Maj|Brig|Sgt|Capt|Cmnd|Sen|Rev|Rep|Revd)
      \.\s)|(?:\b(?:St|Gen|Hon|Prof|Dr|Mr|Ms|Mrs|[JS]r|Col|Maj|Brig|Sgt|Capt|Cmnd|Sen|Rev|Rep|Revd)\.\s[A-Z]\.\s)|(?:\bApr\.\s)|(?:\bAug\.\s)|(?:\bBros\.
      \s)|(?:\bCo\.\s)|(?:\bCorp\.\s)|(?:\bDec\.\s)|(?:\bDist\.\s)|(?:\bFeb\.\s)|(?:\bInc\.\s)|(?:\bJan\.\s)|(?:\bJul\.\s)|(?:\bJun\.\s)|(?:\bMar\.\s)|(?
      :\bNov\.\s)|(?:\bOct\.\s)|(?:\bPh\.?D\.\s)|(?:\bSept?\.\s)|(?:\b\p{Lu}\.\p{Lu}\.\s)|(?:\b\p{Lu}\.\s\p{Lu}\.\s)|(?:\bcf\.\s)|(?:\be\.g\.\s)|(?:\besp
      \.\s)|(?:\bet\b\s\bal\.\s)|(?:\bvs\.\s)|(?:\p{Ps}[!?]+\p{Pe} ))\Z/su',
   '/(?:(?:[\.\s]\p{L}{1,2}\.\s))\Z/su',
   '/(?:(?:[\[\(]*\.\.\.[\]\)]* ))\Z/su',
      '/(?:(?:\b(?:pp|[Vv]iz|i\.?\s*e|[Vvol]|[Rr]col|maj|Lt|[Ff]ig|[Ff]igs|[Vv]iz|[Vv]ols|[Aa]pprox|[Ii]ncl|Pres|[Dd]ept|min|max|[Gg]ovt|lb|ft|c\.?\s
      *f|vs)\.\s))\Z/su',
   '/(?:(?:\b[Ee]tc\.\s))\Z/su',
   '/(?:(?:[\.!?…]+\p{Pe} )|(?:[\[\(]*…[\]\)]* ))\Z/su',
   '/(?:(?:\b\p{L}\.))\Z/su',
   '/(?:(?:\b\p{L}\.\s))\Z/su',
   '/(?:(?:\b[Ff]igs?\.\s)|(?:\b[nN]o\.\s))\Z/su',
   '/(?:(?:[\"”\']\s*))\Z/su',
   '/(?:(?:[\.!?…]
[\x{00BB}\x{2019}\x{201D}\x{203A}\"\'\p{Pe}\x{0002}]*\s)|(?:\r?\n))\Z/su',
   '/(?:(?:[\.!?…]
[\'\"\x{00BB}\x{2019}\x{201D}\x{203A}\p{Pe}\x{0002}]*))\Z/su',
   '/(?:(?:\s\p{L}[\.!?…]\s))\Z/su');
   $after_regexes = array('/\A(?:)/su',
   '/\A(?:[\p{N}\p{Ll}])/su',
   '/\A(?:[^\p{Lu}])/su',
   '/\A(?:[^\p{Lu}]|I)/su',
   '/\A(?:[^p{Lu}])/su',
   '/\A(?:\p{Ll})/su',
   '/\A(?:\p{L}\.)/su',
   '/\A(?:\p{L}\.\s)/su',
   '/\A(?:\p{N})/su',
   '/\A(?:\s*\p{Ll})/su',
   '/\A(?:)/su',
   '/\A(?:\p{Lu}[^\p{Lu}])/su',
   '/\A(?:\p{Lu}\p{Ll})/su');
$is_sentence_boundary = array(false, false, false, false, false, false, false, false, false, false, true, true, true);
   $count = 13;
   $sentences = array();
   $sentence = '';
   $before = '';
   $after = substr($text, 0, 10);
   $text = substr($text, 10);
   while($text != '') {
      for($i = 0; $i < $count; $i++) {
         if(preg_match($before_regexes[$i], $before) && preg_match($after_regexes[$i], $after)) {
            if($is_sentence_boundary[$i]) {
               array_push($sentences, $sentence);
               $sentence = '';
            }
            break;
         }
      }
      $first_from_text = $text[0];
      $text = substr($text, 1);
      $first_from_after = $after[0];
      $after = substr($after, 1);
      $before .= $first_from_after;
      $sentence .= $first_from_after;
      $after .= $first_from_text;
   }
   if($sentence != '' && $after != '') {
      array_push($sentences, $sentence.$after);
   }
   return $sentences;
}
$text = "Hello there, hello from Tokyo, Japan, Universe, Earth.";
print_r(sentence_split($text));

Đầu ra

Điều này sẽ tạo ra kết quả sau -

Array ( [0] => Hello there, hello from Tokyo, Japan, Universe, Earth. )

Văn bản dần dần được lặp lại. Tại bất kỳ thời điểm nào, phần dữ liệu văn bản hiện tại sẽ có 2 phần khác nhau. Trong phần này, một phần sẽ là ứng cử viên chuỗi con xuất hiện trước và ranh giới câu.

Phần còn lại là ứng viên chuỗi con đứng sau ranh giới câu. 20 cặp regex đầu tiên phát hiện các vị trí. Khi ranh giới câu không được xác định, thì trước và sau được tăng dần mà không cần lưu câu mới đó.

Nếu không có cặp nào trùng khớp, sẽ cố gắng so khớp với 3 cặp cuối cùng, từ đó phát hiện ra ranh giới câu.