Это моя текущая функция очистки предложения:
# 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.
Это означает, что все эти требования должны быть выполнены:
Я думаю, что регулярное выражение является очень подходящей технологией для этого. В конце концов, это санация. Не грамматика или синтаксическая коррекция.
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;
}
Я думаю, что буду отвечать на вопросы по одному, так как более разумно сосредоточиться на одной задаче, а не объединять их все вместе.
Для № 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 (. или же …), (?<!\.)(\.{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);
Для № 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);