PHP - 删除重复标点符号?

时间:2012-05-11 04:05:56

标签: php

假设您有以下字符串:Hello... how are you!!?? I'm bored!!

我希望尽可能删除背对背的标点符号,并在类似“!?”的情况下保留问号。过滤后的字符串应如下所示:

Hello. how are you? I'm bored!

最佳答案是解决此问题的最简洁的解决方案。我希望正则表达式是解决这个问题的最好方法,但我对正则表达式的了解非常非常有限,而且我不知道如何解决这个问题。不过,我对非正则表达式解决方案更加满意!对你提供的任何代码的解释 - 除非非常简单 - 也会很好。

谢谢!

3 个答案:

答案 0 :(得分:3)

$str = preg_replace('~[?!]{2,}~', '?', preg_replace('~([.,!?])(\\1+)~', '\\1', $str));

或在一次preg_replace电话中(感谢Alix Axel)

$str = preg_replace(array('~([.,!?])(\\1+)~', '~[?!]{2,}~'), array('\\1', '?'), $str);

只需枚举大括号中你所关注的所有标点符号

UPD :处理!?只是将其与另一个正则表达式嵌套

解释一切意味着什么:

preg_replace('~([.,!?])(\\1+)~', '\\1', $str)

表达式([.,!?])(\\1+)表示 - 只有在.,!?前面至少有一个相同的字符\\1+时才会找到\\1,其中+ - 是对前一个字符的引用匹配,at least one[?!]{2,}

用仅一个字符替换所有这些。

外部表达式find all ? or ! if they are at least 2 in a row表示?,并将其替换为{{1}}

答案 1 :(得分:1)

你可以使用preg_replace:

$a="Hello... how are you!!?? Im bored!!!!!!"; echo preg_replace("/([.!?])+/iS","$1",$a);

=> Hello. how are you? Im bored!

答案 2 :(得分:0)

$string = "Hello... how are you!!?? I'm bored!!"
$new_string = $string;
foreach(array('.',',','?','!') as $value) {
  $i = ;
  do {
    $prev_string = $new_string;
    $string = str_replace($value . $value,$value,$string;
    $i++;
  } while ($string !== $prev_string && $i<100)
}

那摆脱了重复,但没有?!?。

我认为第二种解决方案可行,保留“坏人”的第一位。 如果你想保留最后一个,那么也有解决方案。

<?php
$string = str_split($string);
$new_string = array();
$i = 0;
foreach($string as $key => $char) {
    echo 'Processing: ' . $char . '<br />';
    $prev_key = $key - 1;
    $prev_char = $string[$prev_key];
  if($i!== 0) {
    if(in_array($char,$bad_chars) && in_array($prev_char,$bad_chars) ) {
      // do nothing
    } else {
      $new_string[] = $char;
    }
  } else {
    $prev_char = $char;
    $new_string[] = $prev_char;
  }
  $i++;
}
$string = implode('',$string);
$new_string = implode('',$new_string);
?><br />

<?php echo $string; ?><br />
<?php echo $new_string; ?><br />