Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> PHP

Tách chuỗi thành câu dùng regex trong PHP


Ví dụ

function sentence_split($text) { 
    $before_regexes = 
        array('/(?:(?:[\'"\x{201E}][\.!?\x{2026}][\'"\x{201D}]\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', 
        '/(?:(?:[\.!?\x{2026}]+\p{Pe} )|(?:[\[\(]*\x{2026}[\]\)]* ))\Z/su', 
        '/(?:(?:\b\p{L}\.))\Z/su', 
        '/(?:(?:\b\p{L}\.\s))\Z/su', 
        '/(?:(?:\b[Ff]igs?\.\s)|(?:\b[nN]o\.\s))\Z/su', 
        '/(?:(?:[\'"\x{201D}]\s*))\Z/su', 
        '/(?:(?:[\.!?\x{2026}] [\x{00BB}\x{2019}\x{201D}\x{203A}\'"\p{Pe}\x{0002}]*\s)|(?:\r?\n))\Z/su', 
        '/(?:(?:[\.!?\x{2026}] [\'"\x{00BB}\x{2019}\x{201D}\x{203A}\p{Pe}\x{0002}]*))\Z/su', 
        '/(?:(?:\s\p{L}[\.!?\x{2026}]\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));

Kết quả

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

Văn bản được lặp dần dần. Tại bất kỳ thời điểm, chunk văn bản hiện tại có 2 phần. Phần trước ranh giới câu, phần sau ranh giới câu. 20 cặp regex đầu phát hiện vị trí. Khi không xác định ranh giới, before/after tăng mà không lưu câu mới.

Nếu không cặp nào khớp, thử 3 cặp cuối, phát hiện ranh giới câu.