首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 中英文混合斷句無亂碼:urlencode + 正則實現精準分句

     編輯:PHP 相關知識

問題場景

處理中英文混合文本時,直接按字元數截取或分句極易產生亂碼(多位元組字元被截斷)或標點判斷錯誤(中英文標點混淆)。本文介紹一種「編碼轉換 + 正則匹配 + 解碼還原」的巧妙方案,完美解決中英文混排斷句難題。

核心思路:三步走策略

  1. urlencode 編碼:將所有字元(含中文、標點)轉為 ASCII 安全字串,消除多位元組干擾
  2. 正則匹配:在編碼後字串上按「編碼後標點」精準切分句子
  3. urldecode 解碼:將分割後的片段還原為可讀文本

關鍵編碼對照表

完整實作程式碼

<?php
// 測試:查看標點編碼後樣貌
echo urlencode(',-.-?-!-;-,-。-?-!-;-......') . PHP_EOL;

// 待處理混合文本
$str = "測試測試,測試測試.測試測試?測試測試!測試測試;測試測試,測試測試。測試測試?測試測試!測試測試;測試測試......";

echo "原文:$str\n";

// 核心處理邏輯
$str = urlencode($str);

// 正則模式:匹配「任意字元(非貪婪) + 結尾標點」的組合
// \.{3,6} 匹配 3-6 個連續點號(處理省略號)
$pattern = '/(.*?)(\.{3,6}|%2C|\.|%3F|%21|%3B|%EF%BC%8C|%E3%80%82|%EF%BC%9F|%EF%BC%81|%EF%BC%9B)/';

preg_match_all($pattern, $str, $matches);

$sentences = [];
foreach ($matches[0] as $match) {
    $sentences[] = urldecode($match);
}

var_dump($sentences);

/* 
輸出結果:
array(10) {
  [0]=> string(15) "測試測試,"
  [1]=> string(15) "測試測試."
  [2]=> string(15) "測試測試?"
  [3]=> string(15) "測試測試!"
  [4]=> string(15) "測試測試;"
  [5]=> string(18) "測試測試,"
  [6]=> string(18) "測試測試。"
  [7]=> string(18) "測試測試?"
  [8]=> string(18) "測試測試!"
  [9]=> string(24) "測試測試......"
}
*/
?>

方案優勢分析

原始字元urlencode 後說明
,%2C英文逗號
.%2E (或保持 .)英文句號
?%3F英文問號
!%21英文驚嘆號
;%3B英文分號
,%EF%BC%8C中文逗號 (UTF-8)
。%E3%80%82中文句號 (UTF-8)
?%EF%BC%9F中文問號 (UTF-8)
!%EF%BC%81中文驚嘆號 (UTF-8)
;%EF%BC%9B中文分號 (UTF-8)
......%2E%2E%2E%2E%2E%2E (或 %E2%80%A6)省略號

進階擴展:支援更多語言與標點

function split_sentences($text, $encoding = 'UTF-8') {
    // 通用標點集(可擴展)
    $punctuations = [
        '.', '?', '!', ';', ':', ',',  // 基礎拉丁
        '。', '?', '!', ';', ':', ',', '、',  // 中文
        '.', '?', '!', ';', ':', ',',  // 全形英文
        '…', '...', '。。。',  // 省略號變體
    ];
    
    // 動態構建正則(需對特殊字元轉義)
    $encoded_puncts = array_map(function($p) {
        return preg_quote(urlencode($p), '/');
    }, $punctuations);
    
    $pattern = '/(.*?)(' . implode('|', $encoded_puncts) . ')/u';
    
    $encoded = urlencode($text);
    preg_match_all($pattern, $encoded, $matches);
    
    return array_map('urldecode', $matches[0]);
}

適用場景與限制

  • ✅ 適用:文章摘要生成、語音合成分句、關鍵詞提取前處理、郵件/簡訊內容分段
  • ✅ 適用:UTF-8、GBK、BIG5 等任意編碼環境(urlencode 自適應)
  • ⚠️ 注意:不處理引號內標點(如:「他說:『你好!』」會在 !處斷開)
  • ⚠️ 注意:數字小數點(3.14)、網址、郵箱會被誤切,需預處理保護
  • ❌ 不適用:需要語義理解的複雜 NLP 斷句(需用 jieba、spaCy 等工具)

總結

「urlencode + 正則 + urldecode」是一個極具工程智慧的「降維打擊」技巧:將複雜的多位元組字元邊界問題,轉化為簡單的 ASCII 字串模式匹配問題。代碼簡潔(核心 < 10 行)、效能優異、跨編碼相容、易於擴展。對於「按標點分句」這一高頻需求,是極具性價比的首選方案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
傳統 mb_substr / 正則直匹urlencode 方案
需處理多位元組邊界,易截斷字元編碼後全為單位元組,無邊界問題
中英文標點需分別列舉,正則複雜統一在編碼層面匹配,邏輯清晰
編碼轉換(UTF-8/GBK)需改代碼urlencode 自動適應當前腳本編碼
效能較低(mb_* 函數較慢)純字串操作,效能極佳