Возможно ли замутить такое? (регулярное выражение)

123
djdiplomat
На сайте с 05.08.2009
Offline
136
#11
siv1987:
Ну два альтернативных решений выше уже дали, вот еще одно немного улучшенное

find: /([^\s]+)\s+(?:\1(\s+|$|\.|,))+/
replace: $1$2

исключения юзать по варианту предложенному RiDDi.

А что-то почему то не прокатывает вообще замена...т.е он почему то не юзает по строке.... даже пробовал просто на удаление ставить...

$z = "идет пешеход пешеход по дороге лесной лесной и радуется радуется очень сильно.";

$result = preg_replace ("/([^\s]+)\s+(?:\1(\s+|$|\.|,))+/", "", $z);

echo $result;

Тупо строка без изменений возвращается...

siv1987
На сайте с 02.04.2009
Offline
427
#12

\1 в двойных кавычках \\1

ivan-lev:
Что за задачник такой?

Да, djdiplomat, и почему мы должны их решать за вас, а? Если хотите выучить регулярные выражения начните с чего нибудь полегче. Если за вас будут решать задачи, толкам вы так не научитесь.

---------- Добавлено 11.04.2013 в 20:10 ----------

ivan-lev:
В некоторых языках это "задачей похлеще" назвать нельзя.. python, например:

list($a, $b) = array($b, $a); :)

IL
На сайте с 20.04.2007
Offline
435
#13
siv1987:
list($a, $b) = array($b, $a);

сколько слов лишних-то?! :)

... :) Облачные серверы от RegRu - промокод 3F85-3D10-806D-7224 ( http://levik.info/regru )
F
На сайте с 27.03.2007
Offline
85
#14

Для этого вам нужен паттерн с двойным "assertion" (по-русски переводят как "утверждение").

Сам паттерн ищет слово, после которого следует такое же слово (это первое утверждение), при этом после него НЕ следует слово из стоп-списка (второе утверждение).


$exceptions = array('ipsum', 'incididunt');
$z = "Lorem Lorem ipsum ipsum dolor sit amet, consectetur adipisicing elit, sed sed do eiusmod eiusmod tempor incididunt incididunt ut labore et dolore magna aliqua aliqua";
echo $z . '<br>';
echo preg_replace('#(^|\s+)(\S+)(?=\s+\2)(?!\s+(' . implode('|', $exceptions) . '))(\s+|$)#s', '\4', $z);

Пример в codepad: http://codepad.viper-7.com/0gRrEU

Спасибо за интересную задачку :)

Нужны пояснения - пишите.

siv1987
На сайте с 02.04.2009
Offline
427
#15
fervent:
Для этого вам нужен паттерн с двойным "assertion" (по-русски переводят как "утверждение").

Зачем? Всё сложное ненужно, всё нужное - просто. ©

#(\S+)(?!\s+(' . implode('|', $exceptions) . '))(?:\s+\1)#, '\1'

F
На сайте с 27.03.2007
Offline
85
#16
siv1987:
Зачем? Всё сложное ненужно, всё нужное - просто. ©

#(\S+)(?!\s+(' . implode('|', $exceptions) . '))(?:\s+\1)#, '\1'

Я бы не стал упрощать код без копания в деталях. Примеры того, что делает ваш код:

(в середне строки)

dolorbat batsit amet
в
dolorbatsit amet

(в начале строки)

Lorem orem ipsum ipsum
в
Lorem ipsum ipsum
siv1987
На сайте с 02.04.2009
Offline
427
#17
fervent:
Я бы не стал упрощать код без копания в деталях.

Все равно не все так сложно

$excep = (count($exceptions)) ? '(?!\s+('.implode('|', $exceptions).'))' : '';

echo preg_replace('#(^|\s)(\S+)'.$excep.'(?:\s+\2)+#', '\1\2', $z);

djdiplomat
На сайте с 05.08.2009
Offline
136
#18

fervent, спасибо большое! Остальным тоже спасибо за альтернативные варианты!

PS Я тут вижу, даже небольшой спор возник между профессионалами. Если гуру не против, мне будет очень интересно и полезно узнать, какое же из решений будет сочтено как наиболее приемлемое (идеальное).

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

F
На сайте с 27.03.2007
Offline
85
#19
siv1987:
Все равно не все так сложно

$excep = (count($exceptions)) ? '(?!\s+('.implode('|', $exceptions).'))' : '';
echo preg_replace('#(^|\s)(\S+)'.$excep.'(?:\s+\2)+#', '\1\2', $z);

Вроде ничего сложного. Задача по сути переписать if-условие "если два рядом стоящих слова совпадают" И "они не встречаются в списке стоп-слов" языком регулярок. Для этого позитивные "(?=\s+\2)" и негативные "(?!..." утверждения и сделаны, разве нет?

Разница между моим и вашим кодом в замене "(?=...)" на "(?:...", т.е. позитивное утверждение или суб-паттерн. Не уверен, что именно меняется с точки зрения внутренней логики PRCE. Если оба работают - отлично! :)

siv1987
На сайте с 02.04.2009
Offline
427
#20
djdiplomat:
Если гуру не против, мне будет очень интересно и полезно узнать, какое же из решений будет сочтено как наиболее приемлемое (идеальное).

Лучшее решение то, которое вы сами напишите. :)

Кстати еще один вариант

'/\b(\S+)'.$excep.'(?:\s+\1)+\b/', '\1'

fervent:
Для этого позитивные "(?=\s+\2)" и негативные "(?!..." утверждения и сделаны, разве нет?

С утверждением для исключений согласен, а для проверки шаблона, имхо, лучше подмаска. Да, работать будет, но если слова повторяются не два а три раза?

123

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий