这是一个句子清洁剂。
function sanitize_sentence($string) {
$pats = array(
'/([.!?]\s{2}),/', # Abc. ,Def
'/\.+(,)/', # ......,
'/(!|\?)\1+/', # abc!!!!!!!!, abc?????????
'/\s+(,)/', # abc , def
'/([a-zA-Z])\1\1/'); # greeeeeeen
$fixed = preg_replace($pats,'$1',$string); # apply pats
$fixed = preg_replace('/(?:(?<=\s)|^)[^a-z0-9]+(?:(?=\s)|$)/i', '',$fixed); # bad chunks
$fixed = preg_replace( '/([!?,.])(\S)/', '$1 $2', $fixed); # spaces after punctuation, if it doesn't exist already
$fixed = preg_replace( '/[^a-zA-Z0-9!?.]+$/', '.', $fixed); # end of string must end in period
$fixed = preg_replace('/,(?!\s)/',', ',$fixed); # spaces after commas
return $fixed;
}
这是测试句:
你好[[[[[[]]]]]]朋友.....?你好吗[}}}}}}
它应该返回:
你好朋友.....?你好吗
但它正在回归:
你好朋友。 .. ..?你好吗。
所以有2个问题,我无法找到解决方案:
第二个问题的例子:
这句话不需要结束时间,因为提到的字符无处可寻。
这句话,需要它!为什么?因为它至少包含一个提到的字符
(当然,只有在尚未存在的情况下才能放置结束期)
感谢您的帮助!
答案 0 :(得分:4)
以下是您第一个问题的答案。第三个到最后一个替换是问题:
$fixed = preg_replace( '/([!?,.])(\S)/', '$1 $2', $fixed); # spaces after punctuation, if it doesn't exist already
它将第一个句点与字符类匹配,第二个句点作为非空格字符。然后插入一个空格。由于匹配不能重叠,因此它将匹配第三个和第四个周期并插入空格,依此类推。这可能是最好的解决方法:
$fixed = preg_replace( '/[!?,.](?![!?,.\s])/', '$0 ', $fixed);
以下是您如何处理第二项要求(替换倒数第二位preg_replace
):
$fixed = trim($fixed);
$fixed = preg_replace( '/[!?.,].*(?<![.!?])$/', '$0.', $fixed);
首先,我们摆脱前导和尾随空格,将此问题与尾随时期区分开来。然后preg_replace
将尝试在字符串中找到标点符号,如果是,则匹配所有内容直到字符串结尾。替换将比赛放回原位并追加期限。注意负面的背后。它断言字符串不会以句尾标点符号结尾。