[regexp]помогите плз убрать дубли

Pati_D

В исходной строке нужно удалить дубликатные слова.
пример:
Вход: ааа бббб ввв ааа дддддд
Выход: ааа бббб ввв дддддд

hwh2010

тебе обязательно с помощью regexp эту задачу надо решить? тогда, боюсь, ни фига не выйдет

Serab

Ну как не выйдет? regexp разные бывают ;-)

Pati_D

именно с помощью регэксп

hwh2010

те что не описывают конечные автоматы — это уже извращение какое-то, а не regexp. Ещё и тормозить могут.
А что, ими правда можно все дубли удалить?

hwh2010

не, серьёзно, напиши хоть какие регекспы у тебя?

Pati_D

причем это задачка для начинающего, там должно быть что-то не оч сложное

Serab

А что, ими правда можно все дубли удалить?
я не прожжен в этой теме. Т.е. мне сложно судить на глаз можно или нет.

Serab

Ну вот если ты начинающ(ая :confused: напиши тут regexp, выделяющий отдельное слово, отделенное пробелами.

stilet78

если для начинающего, то задача наверное должна звучать так :

Andbar

<?php
$text = 'ааа бббб ввв ааа дддддд';
$find = '#(?<=\s|^\w+\s.*?)?\s\1#';
$repl = '$1$2';
while($res = preg_replace($find, $repl, $text) and $res!=$text)
$text = $res;
print $text;
?>

ark21

в конце наверное забыл (?=\s|$) , но в цикле вызывать все равно неспортивно..

Serab

давай я сейчас на .NET напишу. Странная шутка в общем.

danilov

".*\ (.+)\ .*\ \1\ "
Это считая, что слова отделены пробелами, причём с обоих сторон.
Можно заморочиться, но мысль ясна.
Копать по '\n - означает n-ую найденную группу'

Andbar

в конце наверное забыл (?=\s|$)
Есть такое :grin:
, но в цикле вызывать все равно неспортивно..
не хотите циклы, получите рекурсию :grin:
<?php
$text = 'ааа бббб ввв ааа дддддд ввв ччч ааа';
//$text = "aaa\naaa";
$find = '#(?<=\s|^\w+\s.*?)?\s\1(\s.*)?$#e';
$repl = 'preg_replace($find, $repl, "$1$2".preg_replace("/\s".preg_quote("$1", "/")."(?=\s|$)/", "", "$3"';
$text = preg_replace($find, $repl, $text);
//while($res = preg_replace($find, $repl, $text) and $res!=$text)
// $text = $res;
print '"'.$text.'"';
?>

upd: просто регекспом не получится, так как повторяться могут разные слова и их зоны повторения могут пересекаться, а поиск следующего вхождения начинается после текущего вхождения.
upd2: поправил код

Andbar

давай я сейчас на .NET напишу. Странная шутка в общем.
А это и не шутка. Скорее всего, регексп предстоит использовать в программе, которая пишется на некотором языке и в большинстве случаев будет какая-то своя специфика в тех или иных мелочах. А так как язык не был указан, никто мне не мешает выбрать его произвольно.

danilov

Заморочился

\W|\A\w+\W|\W.*\W\3(\W|\z)


заменить на

$1$5

Правда оно не сработает на пересекающихся парах
upd поправил

Andbar

Правда оно не сработает на пересекающихся парах
вот именно поэтому я прописал сперва цикл, а потом - рекурсию.

Pati_D

большое-большое спасибо!

pitrik2

просто регекспом не получится
а рекурсию в регэкспы разве еще не добавили?

Andbar

допустим, что-то такое там есть и это может помочь сразу найти все вхождения одного из слов и, возможно, убрать все его повторы (хотя, прочитав соответствующий раздел, я сходу не готов написать регексп, делающий это но как ты собираешься обрабатывать строку с множественными (>2) вхождениями более одного слова исключительна средствами regexp'а (без привлечения средств языка, из-под которого вызывается поиск/замена по регекспу)?

pitrik2

ну я ожидаю там какогонить флага типа: "делать покуда хоть что-то сматчится"
и дальше дать регэксп ищущий 2 одинаковых слова и удаляющий второе
т.е. должно быть что-то типа
s/(\w.*\1)/\1\2/r
s - замена, (\w) - первое слово, (.*) - остальные слова, (\1) - второе слово равное первому, r - флаг рекурсии

danilov


(\W|\A\w+?=(\W|\W.*\W\2\W|\z -> $1

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

apl13

Это считая, что слова отделены пробелами
[[:space:]]

?

Andbar

Думаю, можно убирать и последние, но с темой (? пока полностью не разобрался
с этим сложно, в силу ограничений, наложенных на (?<= и (?<!, а именно - запрета на переменную длину предшествующего подшаблона. Вот если бы в условных подмасках можно было бы просматривать весь предшествующий текст...
Кстати, (\W|\A) можно заменить на \b
Оставить комментарий
Имя или ник:
Комментарий: