preg_replace标点符号前后加space

preg_replace add space before and after of punctuation characters

我有一个词填满了一些标点符号。

$word = "'Ankara'da!?'";

我想在标点符号之前或之后添加 spaces。 除了单词中间的撇号字符。 结果字母或标点之间必须只有一个space。

所需结果:' Ankara'da ! ? '

我在下面尝试并添加了带口音的土耳其语字符。 (因为 \w 没用)

preg_replace('/(?![a-zA-Z0-9ğüışöçİĞÜŞÖÇ])/ig', " ", $word);

结果:'Ankara 'da ! ? '

如果只需要在标点符号之间加单个空格,避免在字符串的start/end处加,可以采用如下解决方法:

$word = "'Ankara'da!?'";
echo trim(preg_replace_callback('~\b\'\b(*SKIP)(*F)|\s*(\p{P}+)\s*~u', function($m) {
    return ' ' . preg_replace('~\X(?=\X)~u', '[=10=] ', $m[1]) . ' ';
}, $word)); // => ' Ankara'da ! ? '

参见 the PHP demo

\b\'\b(*SKIP)(*F) 部分匹配并跳过所有用字符(字母、数字、下划线和一些很少使用的字符)括起来的 '\s*(\p{P}+)\s* 部分匹配 0+ 个空格,然后将 1+ 个标点符号(包括 _!)捕获到第 1 组,然后匹配任何 0+ 个空格。然后,在每个 Unicode 字符 (\X) 之后添加单个空格,后面跟另一个 Unicode 字符 ((?=\X))。外面的 leading/trailing 空格稍后会用 trim()).

删除

有一种方法可以做到这一点

$word = "'Ankara'da!?'";
echo preg_replace('~^\s+|\s+$|(\s){2,}~u', '', 
    preg_replace('~(?!\b\'\b)\p{P}~u', ' [=11=] ', $word)
);

another PHP demo

'~(?!\b\'\b)\p{P}~u'模式匹配任何不是'用字符括起来的标点符号,并且这个符号用空格括起来,然后'~^\s+|\s+$|(\s){2,}~u'模式用于删除所有空格在字符串的 start/end 并将所有其他位置的所有空格缩小为 1。