句子大小写转换正则在带引号等场景下失效的修复方案咨询
解决句子首字母大写时引号结尾内容丢失的问题
原使用以下正则实现句子首字母大写(同时规避N.B.C.这类缩写):
/(?:\d+\.\d+|\b[A-Z](?:\.[A-Z])*\b\.?|[^.!?])+[.!?…](?:\s|\Z)/
配套PHP函数:
function sentence_case($text) { // Split into sentences. Therefore, find all text that ends // with punctuation followed by white space or end of string. preg_match_all('/(?:\d+\.\d+|\b[A-Z](?:\.[A-Z])*\b\.?|[^.!?])+[.!?…](?:\s|\Z)/', $text, $sentences); $sentences = $sentences[0]; // Capitalize the first letter of each sentence foreach ($sentences as &$sentence) { $sentence = ucfirst($sentence); } // Combine sentences return implode('', $sentences); }
该函数处理普通句子正常,但当句子以引号等闭合符号结尾时,会丢失对应内容。例如输入:
$text = 'first sentence. second sentence! "third sentence?"';
实际输出仅保留前两个句子,丢失引号内内容:
First sentence. Second sentence!
期望输出应包含引号内内容并正确大写首字母:
First sentence. Second sentence! "Third sentence?"
修改方案
调整正则表达式,允许句子结束标点后跟随可选的闭合符号(如引号、括号等),确保这类内容被纳入匹配范围。
修改后的正则表达式:
/(?:\d+\.\d+|\b[A-Z](?:\.[A-Z])*\b\.?|[^.!?])+[.!?…](?:["'”’\)\]]*)(?:\s|\Z)/
修改后的PHP函数:
function sentence_case($text) { preg_match_all('/(?:\d+\.\d+|\b[A-Z](?:\.[A-Z])*\b\.?|[^.!?])+[.!?…](?:["'”’\)\]]*)(?:\s|\Z)/', $text, $sentences); $sentences = $sentences[0]; foreach ($sentences as &$sentence) { $sentence = ucfirst($sentence); } return implode('', $sentences); }
修改说明
- 在句子结束标点
[.!?…]后新增(?:["'”’\)\]]*)分支,匹配0个或多个常见闭合符号(含中英文引号、右括号、右方括号),确保这类符号及内部内容被包含在句子匹配中 - 保留原有的缩写规避逻辑,不影响N.B.C.、U.S.A.这类缩写的识别与处理
内容的提问来源于stack exchange,提问作者Henrik Petterson
相关产品推荐
相关产品推荐

