powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Выделение повторяющихся слов через иерархию и регулярки
24 сообщений из 24, страница 1 из 1
Выделение повторяющихся слов через иерархию и регулярки
    #39470554
GetShuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Приветствую.

Есть задача: выделить из фраз одинаковые, стоящие рядом слова.

Код:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
with input as 
(select 'Мама мыла раму раму мыла мама' as text
from dual
union
select 'Кулон лон слон слон слон Книга     книга' as text
from dual 
union 
select 're re rere rere rerere rerere re re rererere rererere re re' as text
from dual),
/*разбиение по позициям*/
position as 
(select distinct text, level as lev, 
      regexp_instr(upper(text), '(( |^)(\w+)) +\3', 1, level, 0) as begin,
      regexp_instr(upper(text), '(( |^)(\w+)) +\3', 1, level, 1) as finish
from input
connect by level <= regexp_count(text, ' +') )
/*удаление лишних пробелов*/
select decode(lev, 1, text, ' ')as input_string,
regexp_replace(regexp_replace(substr(text, begin, finish - begin), ' +', ' '), '^ ?', '') as duplicate_words
from position
where begin != finish
order by text, lev;



Результат:

re re rere rere rerere rerere re re rererere rererere re re re re
rere rere
rerere rerere
re re
rererere rererere
re re
Кулон лон слон слон слон Книга книга слон слон
Книга книга
Мама мыла раму раму мыла мама раму раму

Все пучком.
НО! Для фразы "ere re rere rere rerere rerere re re rererere rererere re re" такой результат:
re re rere rere
re re
rererere rererere re re

А должно вернуть:
rere rere rerere rerere
re re
rererere rererere
re re

Прошерстил местные топики:
http://www.sql.ru/forum/709654/regulyarnye-vyrazheniya
http://www.sql.ru/forum/1019130/zadachi-na-regulyarnye-vyrazheniya
Все предлагаемые в них варианты допускают ту же ошибку.

Т.е. если во фразе есть одно непарное слово, все слетает.
Косяк явно в регулярке.
Прошу помочь разобраться, ибо сил уже нет.
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470557
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GetShuk,

Try this REGEXP_REPLACE шаблон
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470570
GetShuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dbms_photoshop, это удаление дубликатов из строки. А мне нужно делать выборку повторяющихся, стоящих рядом слов.
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470576
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GetShuk,

Я думал если знать как удалить дубликаты, то можно догадаться как удалить все НЕ дубликаты или как "выделить" дубликаты.

PS. Разбиение + distinct - тот еще говнокод.
Нормальный разработчик при наличии повторяющихся строк пытается избавиться от причины а не следствия.
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470579
GetShuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dbms_photoshop, во-первых, я студент, а во-вторых, так задача поставлена преподом.
Поясните, хотя бы минимально, каким образом переписать это

Код: plsql
1.
2.
select regexp_replace(str, '([^ ]+)( \1)+( |$)', '\1\3') str_dist
from (select 'ere re rere rere rerere rerere re re rererere rererere re re' str from dual)



чтобы удалить НЕ дубликаты из строки.
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470588
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GetShukя студентКакая разница. Хоть ты школьник на уроке информатики.
Если код после выполнения возвращает не то, что ожидается, то нормальный подход это искать причину и исправлять, а говнокод - это вставлять костыль (в твоем случае distinct), чтоб из неправильного результата получить правильный (убрать дубли в твоем случае).
GetShukзадача поставлена преподом.
Поясните, хотя бы минимально, каким образом переписать это

Код: plsql
1.
2.
select regexp_replace(str, '([^ ]+)( \1)+( |$)', '\1\3') str_dist
from (select 'ere re rere rere rerere rerere re re rererere rererere re re' str from dual)



чтобы удалить НЕ дубликаты из строки.А почему ты не задаешь уточняющие вопросы преподу?
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470589
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GetShuk,

В лоб
Код: plsql
1.
2.
3.
4.
5.
6.
SQL> select regexp_replace(regexp_replace(replace(str, ' ', ';;'), '(^|;)([^;]+)(;;\2)+(;|$)', '\4'), ';+', ' ') str_dist
  2    from (select 'ere re rere rere rerere rerere re re rererere rererere re re qwe qwe1 asd sd ert ert pin pin' str from dual);

STR_DIST
-----------------------
ere re qwe qwe1 asd sd


Вполне вероятно можно изящнее.
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470592
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Упс, написал для противоположной задачи.
Ладно, помогу минимально. Изучи что означают "\цифра".
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470595
GetShuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dbms_photoshop,
1) препод принципиальный - никаких подсказок
2) это обратные ссылки на выражение в скобках. Но в строке на замену в regexp_replace они ставят в тупик.
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470602
GetShuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dbms_photoshop, не совсем понял, каким образом происходит удаление дубликата при такой регулярке. По факту '(^|;)([^;]+)(;;\2)+(;|$)' просто описывает структуру анализируемой "фразы"
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470605
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GetShuk,

В третьей паре скобок ссылка на вторую пару скобок для этого примера, при этом после третьей пары скобок стоит +.
Это значит что если произошел матч, то значения во второй и третье паре скобок одинакове или иными словами - дубль.

Трюкачества с заменой одинарного разделителя на двойной - это чтоб правильно обработать случаи когда одно слово является частью другого.
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470607
GetShuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dbms_photoshop, это понял.
Но как написать обратную задачу пока хз.
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470608
GetShuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dbms_photoshop, пол логике нужно отрицание сделать и все. Но как?
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470632
coborhc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может так?
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
with
  input as (
    select 'Мама мыла раму раму мыла мама' as text from dual
    union all select 'Кулон лон слон слон слон Книга     книга' as text from dual
    union all select 're re rere rere rerere rerere re re rererere rererere re re' as text from dual)
select
  text,
  (select
    collect(distinct regexp_substr(text, '\w+', 1, level))
    from dual
    where regexp_substr(text, '\w+', 1, level) = regexp_substr(text, '\w+', 1, level + 1)
    connect by level <= regexp_count(text, '\s+') + 1) as res
  from input
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470637
GetShuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
coborhc, "inconsistent datatypes: expected %s got %s"
И коллекции использовать нельзя.
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470638
GetShuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
coborhc, результат выполнения этого скрипта покажите. пожалуйста
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470639
GetShuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
У меня еще был такой вариант:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
with input as 
(select 'Мама мыла раму раму мыла мама' as text
from dual
union
select 'Кулон лон слон слон слон Книга     книга' as text
from dual 
union 
select 'ere re rere rere rerere rerere re re rererere rererere re re' as text
from dual),

positions as 
(select distinct text, level as lev, 
      regexp_instr(upper(text), '(([^ ]{2,})( |,|$))', 1, level, 0) as begin, 
      regexp_instr(upper(text), '(([^ ]{2,})( |,|$))', 1, level, 1) as finish 
from input
connect by level <= regexp_count(text, ' +') + 1 )

--,full_table as(

select decode(lev, 1, text, ' ') as input_string, lev,
regexp_replace(regexp_replace(substr(text, begin, finish - begin), ' +', ' '), '^ ?', '') as duplicate_words
from positions
where begin != finish
order by text, lev
--)
/*здесь должен быть финальный селект*/


Здесь идет корректное разбиение на слова по уровням, только не понял как в итоге в финальном селекте организовать сравнение слов по этим уровням по принципу 1лвл-2лвл, 2-3, 3-4 и т.д.
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470643
coborhc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если без коллекции:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
with
  input as (
    select 'Мама мыла раму раму мыла мама' as text from dual
    union all select 'Кулон лон слон слон слон Книга     книга' as text from dual
    union all select 're re rere rere rerere rerere re re rererere rererere re re' as text from dual)
select
  text,
  (select
    listagg(regexp_substr(text, '\w+', 1, level), ' ') within group (order by rownum)
    from dual
    where regexp_substr(text, '\w+', 1, level) = regexp_substr(text, '\w+', 1, level + 1)
    connect by level <= regexp_count(text, '\s')) as xx
  from input



и еще непонятно, в качестве результата что должно получиться?
если совпала пара - то оба слова, или достаточно одного из пары?
а если это слово в тексте образует более одной пары (как "re")?
или если подряд 3 одинаковых слова (как "слон")?

я конечно видел результат исходного запроса, но мне не понятно - так сделано, потому что так требуется или просто иначе не получилось?
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470644
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GetShukУ меня еще был такой вариант:
Код: plsql
1.
distinct


Я поначалу тебя попытался направить в нужное русло поскольку ты показал, что воспользовался поиском, поэтому была надежда, что не полный лентяй.
Но по поводу distinct ты либо упорно не хочешь слушать либо совершенно не доходит.

Короче если без разбиения строки на слова, то как-то так
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SQL> with t(str) as
  2  (select '123 23 123 12 123 123 12 444 44 55 55 789 89 890' from dual
  3  union all select 'ere re rere rere rerere rerere re re re re qwe qwe1 asd sd ert ert pin pin' from dual)
  4  select regexp_replace(regexp_replace(regexp_replace(groups, '#[^#;]+;+[^#]+#'),
  5                                       ';+', ' '),
  6                        '#+', ' ') non_dups,
  7         regexp_replace(regexp_replace(regexp_replace(groups, '#[^#;]+#'),
  8                                       ';+', ' '),
  9                        '#+', ' ') dups
 10    from (select regexp_replace(replace(str, ' ', ';;'),
 11                                '(^|;)(([^;]+)(;;\3)*)(;|$)',
 12                                '#\2#') groups
 13            from t);

NON_DUPS                                 DUPS
---------------------------------------- ------------------------------------------------------------
 123 23 123 12 12 444 44 789 89 890       123 123 55 55
 ere re qwe qwe1 asd sd                   rere rere rerere rerere re re re re ert ert pin pin



А если с разбиением, то тебе сначала надо будет разбить, а потом применить логику для start_of_group.
И то и другое есть на форуме если поискать, но я не вижу смысла разбивать когда этого можно не делать.
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470645
GetShuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
coborhc, требуется именно так, как в 1 посте указано
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470646
GetShuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dbms_photoshop, именно, что не доходит. С этой задачей уже не 1ый день сижу.
Без разбиения совсем было не понятно, как делать.
Что означает # в регулярках?
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470647
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GetShukЧто означает # в регулярках?Просто маркер для разбиения на группы одинаковых слов.
Потом в первом случае из строки вырезаются группы с более чем одним словом.
Во втором случае вырезаются группы состоящие в точности из одного слова (соответственно остаются дубли).
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470649
GetShuk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dbms_photoshop, спасибо, буду разбирать.
P.S. Не все люди ленивые идиоты.
...
Рейтинг: 0 / 0
Выделение повторяющихся слов через иерархию и регулярки
    #39470652
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GetShuk,

Я в тебя верю. Удачи!

У меня приступ доброты, поэтому держи с разбиением и склейкой

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SQL> with t(str) as
  2  (select '123 23 123 12 123 123 12 444 44 55 55 789 89 890' from dual
  3  union all select 'ere re rere rere rerere rerere re re re re qwe qwe1 asd sd ert ert pin pin' from dual)
  4  select listagg(decode(cnt, 1, token), ' ') within group (order by ord) non_dups,
  5         listagg(decode(cnt, 1, null, token), ' ') within group (order by ord) dups
  6    from (select t2.*, count(*) over(partition by str, grp) cnt
  7            from (select t1.*, sum(sign) over(partition by str order by ord) grp
  8                    from (select t.*, a.*, decode(token, lag(token) over(partition by str order by ord), 0, 1) sign
  9                            from t
 10                           cross apply (select rownum ord, regexp_substr(t.str, '[^ ]+', 1, rownum) token
 11                                          from dual
 12                                       connect by rownum <= regexp_count(t.str, '[^ ]+')) a) t1) t2) t3
 13   group by str;

NON_DUPS                                 DUPS
---------------------------------------- ------------------------------------------------------------
123 23 123 12 12 444 44 789 89 890       123 123 55 55
ere re qwe qwe1 asd sd                   rere rere rerere rerere re re re re ert ert pin pin
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Выделение повторяющихся слов через иерархию и регулярки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]