regex — санация предложения в PHP с помощью preg_replace

Это моя текущая функция очистки предложения:

# sanitize sentence
function sanitize_sentence($string) {
$string = preg_replace("/(?<!\d)[.,!?](?!\d)/", '$0 ', $string); # word,word. > word, word.
$string = preg_replace("/(^\s+)|(\s+$)/us", "", preg_replace('!\s+!', ' ', $string)); # " hello    hello " > "hello hello"return $string;
}

Запуск некоторых тестов с этой строкой:

$string = '     Helloooooo my frieeend!!!What are you doing??    Tell me what you like...........,please. ';

Результат:

echo sanitize_sentence($string);
Helloooooo my frieeend! ! ! What are you doing? ? Tell me what you like. . . . . . . . . . . , please.

Как вы видите, мне уже удалось решить некоторые из требований, но я все еще застрял с некоторыми деталями. Конечный результат должно быть:

Helloo my frieend! What are you doing? Tell me what you like..., please.

Это означает, что все эти требования должны быть выполнены:

  1. Там может быть только один или три последовательных периода . или же
  2. Может быть только одна последовательная запятая ,
  3. Может быть только один знак вопроса подряд ?
  4. Может быть только один последовательный восклицательный знак !
  5. Письмо не может повторяться более двух раз в слове. Например.: масса (право), masss (неправильно, и должен быть преобразован в масса)
  6. Пробел должен быть добавлен всегда после этих символов .,!? Это уже работает нормально!
  7. В случае 3 последовательных периодов пробел добавляется только после последнего периода.
  8. Лишние пробелы (более одного пробела) должны быть исключены и обрезаны с обоих концов предложений. Это уже работает нормально!

0

Решение

Я думаю, что регулярное выражение является очень подходящей технологией для этого. В конце концов, это санация. Не грамматика или синтаксическая коррекция.

function sanitize_sentence($i) {

$o = $i;

//  There can be only one or three consecutive periods . or ...
$o = preg_replace('/\.{4,}/','… ',$o);
$o = preg_replace('/\.{2}/','. ',$o);

//  There can be only one consecutive ","$o = preg_replace('/,+/',', ',$o);

//  There can be only one consecutive "!"$o = preg_replace('/\!+/','! ',$o);

//  There can be only one consecutive "?"$o = preg_replace('/\?+/','? ',$o);

//  we just preemptively added a bunch of spaces.
//  Let's remove any spaces between punctuation marks we may have added
$o = preg_replace('/([^\s\w])\s+([^\s\w])/', '$1$2', $o);

//  A letter cannot repeat itself more than 2 times in a word
$o = preg_replace('/(\w)\1{2,}/','$1$1',$o);

//  Extra spaces should be eliminated
$o = preg_replace('/\s+/', ' ', $o);
$o = trim($o);

// we want three literal periods, not an ellipsis char
$o = str_replace('…','...',$o);

return $o;
}
1

Другие решения

Я думаю, что буду отвечать на вопросы по одному, так как более разумно сосредоточиться на одной задаче, а не объединять их все вместе.

Для № 5, я предлагаю ([a-z])(\1{0,1})\1* заменено на $1$2 как видно в этом примере.

Требуется вход

     Helloooooo my frieeend!!!What are you doing??    Tell me what you like...........,please.

и производит вывод

     Helloo my frieend!!!What are you doing??    Tell me what you like...........,please.
1

Для № 1 (. или же ), (?<!\.)(\.{3}|\.)\.*\s* можно заменить на $1 (обратите внимание на пробел), как видно из этот пример.

Это занимает

     Helloooooo my frieeend!!!What are you doing??    Tell me what you like...........,please.

и производит вывод

     Helloooooo my frieeend!!!What are you doing??    Tell me what you like... ,please.

Как видите, вы получите фанк ... , персонаж, который является еще одной вещью, которую вы, возможно, должны проверить. Вы можете проверить на наличие ., прежде чем делать эту очистку или . , (пробел между) после, если у вас нет другого правила, которое вы хотите использовать для удаления нескольких вхождений знаков препинания.

Сгенерированный для этого код с сайта regex101.com выглядит следующим образом:

$re = "/(?<!\\.)(\\.{3}|\\.)\\.*\\s*/";
$str = "     Helloooooo my frieeend!!!What are you doing??    Tell me what you like...........,please. ";
$subst = "$1 ";
$result = preg_replace($re, $subst, $str);
0

Для № 2, № 3 и № 4, вы можете искать ([,?!])\1+\s* и заменить на $1 (обратите внимание на пробел после), как в этот пример.

Это занимает

     Helloooooo my frieeend!!!What are you doing??    Tell me what you like...........,please.

и производит

     Helloooooo my frieeend! What are you doing? Tell me what you like...........,please.

Сгенерированный код будет выглядеть так:

$re = "/([,?!])\\1+\\s*/";
$str = "     Helloooooo my frieeend!!!What are you doing??    Tell me what you like...........,please. ";
$subst = "$1 ";
$result = preg_replace($re, $subst, $str);
0
По вопросам рекламы [email protected]