Computer >> 컴퓨터 >  >> 프로그램 작성 >> PHP

PHP에서 정규식을 사용하여 문자열을 문장으로 분할

<시간/>

예시

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));

출력

이것은 다음과 같은 출력을 생성합니다 -

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

텍스트는 점차적으로 반복됩니다. 어느 시점에서든 현재 텍스트 데이터 청크는 2개의 다른 부분을 갖습니다. 여기서 한 부분은 문장 경계 앞에 나타나는 부분 문자열 후보가 됩니다.

다른 부분은 문장 경계 뒤에 오는 부분 문자열 후보입니다. 처음 20개의 정규식 쌍은 위치를 감지합니다. 문장의 경계가 식별되지 않을 경우, 새로운 문장을 저장하지 않고 앞뒤가 증가합니다.

일치하는 쌍이 없으면 마지막 3개의 쌍으로 일치를 시도하여 문장 경계를 감지합니다.