2

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

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

Hello. how are you? I'm bored!

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

谢谢!

4

3 回答 3

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并将其替换为?

于 2012-05-11T04:07:32.850 回答
1

你可以使用 preg_replace:

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

=> Hello. how are you? Im bored!
于 2012-05-11T04:15:27.363 回答
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)
}

这摆脱了重复但不是?!?。

我认为第二个解决方案会起作用,保持“bad_chars”的第一个。如果您想保留最后一个,也有解决方案。

<?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 />
于 2012-05-11T04:26:12.847 回答