Замена каждого n-ого найденого символа в строке

Alexxx

Guest
Замена каждого n-ого найденого символа в строке

Здравствуйте.
Возникла ситуация примерно такого типа:
Нужно заменить в тексте знак препинания "." в конце каждогго n-ого предложения на "!!!"
str_replace() не подходит так как она заменяет ВСЕ вхождения строки поиска, а нужно, к примеру, только каждое 5-ое.
Кто нибудь может подсказать как это осуществить?
 

sakon

П..и.н..ок
например так - проверяешь символ на соответствие точке. При нахождении точки +1. Каждую 5 точку меняешь на !!!
или так - разбиваешь регом текст, и в каждой пятой строке меняешь . на !!!
 

Invisibility

Guest
А если в тексте троеточие ? =))

-~{}~ 08.02.05 20:55:

Я предлагаю сначало заменить все "..", "...", "...." на что-нить другое, например "%dot%%dot%", а потом заниматься тем, что посоветывал sakon =)

Останется лишь зменить %dot% обратно на точки =)
 

Alexxx

Guest
Работает ужасно долго даже при небольшом размере строки. Предполагается, что строка будет вмещать текст более 50 000 символов. Возможно ли решить задачу с помощью регулярных выражений? Может кто-нибудь тоже испытывал потребность в замене каждого n-ого слова среди найденных и может поделится подходящей функцией?
Заранее благодарен.
 

SelenIT

IT-лунатик :)
Как вариант: разбить текст по точкам в массив ([m]explode[/m]), а потом в цикле добавлять элементы этого массива к строке. Если новым элемент длинее одного символа (или другого минимального значения) - увеличиваем счетчик (так решаем проблему не только многоточий, но и сокращений и т.д. и т.п.). Пока счетчик меньше 4 - после этого элемента добавляем точку. Когда счетчик достигнет 4 - после этого элемента добавляем требуемую строку (в данном случае "!!!"), а счетчик обнуляем.
 

Нечто

Психолог РНРClub
Еще можно что-то типа этого:
PHP:
$str = 'asdfasdf. asdfasdf. asdfasdf. asdfasdf. asdfasdf. asdfasdf.';

$offset = 0;
$count = 0;
while($offset = strpos($str, '.', $offset+1)) {
    $count++;
    if(!($count%5)) $str = substr_replace($str,'!!!', $offset, 1);
}

echo($str);
 

IBSN

Новичок
как идиотизм, хихи:
PHP:
$newstring = 'one "a" , two "a", three "a", four "a", five "a", six "a", seve "a"';
$int = 5;
$chr = 'a';
$chr_to = '5';
$pos = 0;

for($i = 1; $i <= $int; $i++) {	
	$pos = strpos($newstring, $chr, $pos+1);
	if($i == $int)
		$newstring[$pos] = $chr_to;
}

echo $newstring;
 

SelenIT

IT-лунатик :)
А еще (опять же имхо) можно в свете вышеозвученных идей поколдовать с [m]strtok[/m]:
PHP:
// переменная $text содержит исходный текст
$newtext = '';
$i = 1;
$from = '.'; // что меняем
$to = '!!!'; // чем меняем
$freq = 5; // количество предложений от замены до замены
$min_sentence = 2; // минимальная длина "предложения"
$token= strtok($text,$from);
while ($token) {
   if (strlen($token) > $min_sentence) $i++;
   $newtext .= $token;
   if ($i==$freq) {
      $i=1;
      $newtext .= $to;
   }
   else $newtext .= $from;
   $token= strtok($from);
}
echo $newtext;
 

Vasya

Guest
PHP:
$s = "1 1 1. 2 2... 3 3 3. 4. 5... 6. 7. 8.
9. 10. 11.. 12... 13. 14.. 15... 16.";
echo preg_replace("/((?:[^\.]+\.+){4}[^\.]+)\.+/s", "\\1!!!",$s ) ;
 
Сверху