Предположим, у вас есть следующая строка: Hello... how are you!!?? I'm bored!!
Hello... how are you!!?? I'm bored!!
Я хочу, чтобы везде, где это было возможно, удалялась пунктуация «спина к спине», а вопросительные знаки сохранялись в случае ситуации, подобной «!?». Отфильтрованная строка должна выглядеть следующим образом:
Hello. how are you? I'm bored!
Лучший ответ – самое сжатое решение, которое решает эту проблему. Я ожидаю, что регулярные выражения будут лучшим способом решения этого вопроса, но мои знания о регулярных выражениях очень, очень ограничены в лучшем случае, и я не знаю, как это решить. Однако я более чем умею с решениями, не относящимися к регулярному выражению. Объяснение любого кода, который вы предоставляете, – если только не дьявольски прост – тоже будет приятным.
Спасибо!
$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
find all ? or ! if they are at least 2 in a row
find all ? or ! if they are at least 2 in a row
и заменить его ?
вы можете использовать preg_replace:
$a="Hello... how are you!!?? Im bored!!!!!!"; echo preg_replace("/([.!?])+/iS","$1",$a); => Hello. how are you? Im bored!
$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) }
Это избавляет от дубликатов, но не?!?.
Я думаю, что это второе решение будет работать, сохраняя FIRST из ваших «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 />