只用一个正则表达式去除多个标点符号和空格?

时间:2014-05-21 12:57:16

标签: php regex preg-replace

我得到了什么:

array(4) {
  [0]=>
  string(7) "text???"
  [1]=>
  string(7) "???text"
  [2]=>
  string(11) "text???text"
  [3]=>
  string(24) "text ? ? ?    ? ?   text"
}

我想要的是什么:

array(4) {
  [0]=>
  string(5) "text?"
  [1]=>
  string(6) "? text"
  [2]=>
  string(10) "text? text"
  [3]=>
  string(10) "text? text"
}

我的方法:

<?php

$array = array (
  "text???",
  "???text",
  "text???text",
  "text ? ? ?    ? ?   text"
);

foreach ($array as &$string) {
  $string = preg_replace('!(\s|\?|\!|\.|:|,|;)+!', '$1 ', $string);
}

var_dump($array);

结果:

array(4) {
  [0]=>
  string(6) "text? "
  [1]=>
  string(6) "? text"
  [2]=>
  string(10) "text? text"
  [3]=>
  &string(9) "text text"
}

结论:我的方法有两个我不知道的缺陷。首先,它在每个替换后面添加一个空格,即使它是字符串的结尾。我假设我可以在trim之后使用preg_replace,但如果可能的话,我宁愿通过正则表达式删除它,所以我不需要。其次它打破就像上面例子中的最后一个因为某种原因。

1 个答案:

答案 0 :(得分:2)

忽略你的上一个例子text ? ? ? ? ? text,有一个非常简单的正则表达式,可以删除已定义集合中的重复字符:

([?!.:,;]|\s)\1+

这将匹配紧跟一个或多个相同字符的任何标点符号或空白字符。用于PHP preg_replace()

$value = preg_replace('/([?!.:,;]|\s)\1+/', '$1 ', $value);

Codepad Example上述内容。

现在,这个正则表达式不适用于你的最后一个例子,因为在你的上一个例子中,你拥有的唯一重复字符是几个空格;但是,如果我假设您可以删除跟随其他标点符号的任何标点符号(例如hi!?成为hi!),我们就可以使用以下内容:

([?!.:,;])[?!.:,;\s]+

此正则表达式将找到任何标点符号,后跟任意数量的标点符号空格字符。在上面的preg_replace中使用:

$value = preg_replace('/([?!.:,;])[?!.:,;\s]+/', '$1 ', $value);
扩展正则表达式的

Codepad Example

注意:第二个正则表达式不会删除重复的空格,如果whitepsace是&#34;第一个&#34;事情,例如在文本text ?text;这样做的原因是,在你的例子中,你有它&#34;使用&#34;它找到的第一个标点符号与它找到的第一个重复字符相对。如果这是一个问题,我建议使用后续正则表达式来替换所有重复的空格:

$value = preg_replace('/\s\s+/', ' ', $value);