Как мога да заменя всички дублиращи се препинателни знаци с единични препинателни знаци в PHP?

Има ли ефективен начин за замяна на всички дублирани небуквено-цифрови знаци с единични знаци?

Този въпрос принуждава човек да бъде ясен относно пунктуационните знаци:

PHP - Премахване на дублиращата се пунктуация?

Така:

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

Възможно ли е да се постигне същия резултат, но за ВСИЧКИ знаци, които не са буквено-цифрови, без изрично да се споменават по име?

Ето един случай на употреба:

Hello...  how   are you!!??  I''m bored!!----!!!&&&&&^^^^%%%(()))((<<<<<

to

Hello. how are you!? I'm bored!-!&^%()(<

АКТУАЛИЗАЦИЯ

За съжаление горното навлиза твърде дълбоко в един случай на употреба: http://. Как може да се запази двойно / за URL адреси (или просто когато следват :), но да не се позволява редовно повтаряне / или дори повече от 2 / след :. Ето един случай на употреба:

My ////favorite//// site is http://///example.com!!!!!!!

става:

My /favorite/ site is http://example.com!

person Ryan    schedule 14.01.2015    source източник


Отговори (1)


Можеш да използваш:

$str = preg_replace('~((?<!:)[^\p{L}\p{N}])\1+~u', '$1', $str);
//=> Hello. how are you!? I'm bored!-!&^%()(<

Демо на RegEx

  • [^\p{L}\p{N}] - Съвпада с всичко друго освен буквено-цифров символ на Unicode
  • (?<!:) - Съвпадение само ако не е предшествано от :, за да се погрижите за http://...
  • ([^\p{L}\p{N}]) - Заснемане по-горе в група #1 за обратна справка
  • \1+ - Съпоставете една или повече от уловената група #1, като по този начин се уверите, че съвпадат 2 или повече от същите, които не са буквено-цифрови
  • Заменете го с $1, т.е. заснетия небуквено-цифров знак
person anubhava    schedule 14.01.2015
comment
Страхотна работа @anubhava. За съжаление навлязох твърде дълбоко в един случай на употреба: http://. Възможно ли е да се изключи този случай на употреба (://), като същевременно се замени този случай на употреба: (hello////////there!)? Вижте преработения въпрос по-горе за допълнителни разяснения. Благодаря отново, че ме докарахте дотук. - person Ryan; 15.01.2015