PDA

Показать полную графическую версию : Как в файле Word найти дубликаты наборов символов (кусков текста)


Страниц : [1] 2

sl.oleg@fb
20-11-2016, 15:30
Здравствуйте.
Подскажите, кто знает:
Как в файле Word найти дубликаты наборов символов (кусков текста) с минимальной длиной, заданной в качестве параметра. Сами наборы символов не задаются - они программно обнаруживаются в тексте, ограничиваясь лишь их минимальной длиной.
Возьмем для примера такой тест:

"Мой дядя самых честных правил,
Когда не в шутку занемог,
Он уважать себя заставил
И лучше выдумать не мог самых честных.
Его пример другим наука;
Но, боже мой, какая скука
С больным сидеть и день и ночь,
самых честных Не отходя ни шагу прочь!"

В качестве параметра минимальной длины набора совпадающих символов примем например 10.
Тогда программа должна найти и указать (подсветкой или еще как-то) три вхождения "самых чест" (отмечены жирным шрифтом на примере).
Если таких дубликатов (разных дубликатов имеется ввиду) будет несколько, то программа должна сначала показать их список, а потом, когда пользователь выберет интересующее его текст дубликата, показать в общем тексте все его вхождения (напр.все тем же цветом). Далее можно посмотреть второй набор дубликатов и т.д.
Существуют ли в природе такие программы?

Iska
20-11-2016, 16:03
Тогда программа должна найти и указать (подсветкой или еще как-то) три вхождения "самых чест" (отмечены жирным шрифтом на примере). »
А также:
_самых честных - 2 шт
самых честных - 3 шт
самых честных - 3 шт
самых честных - 3 шт
самых честных_ - 2 шт

sl.oleg@fb
20-11-2016, 16:12
Цитата Iska:
_самых честных - 2 шт самых честных - 3 шт самых честных - 3 шт самых честных - 3 шт самых честных_ - 2 шт »

Как вариант - так как вы отметили, но я бы предпочел, чтоб программа блокировала проверку внутри первого набора найденный дубликатов.
Или же подобные коллизии должны разруливаться на уровне настроек (учитывать/НЕучитывать пробелы или знаки конца абзаца, конца строки и т.п.; искать/НЕискать внутри найденных дубликатов; расширять/НЕрасширять выделение дубликатов на всю строку, характерную для совпадений (в моем примере до "самых честных" - опять-таки включать здесь или не включать пробел в выделение - настраивать опционально).

Iska
20-11-2016, 16:38
Как вариант - так как вы отметили, но я бы предпочел, чтоб программа блокировала проверку внутри первого набора найденный дубликатов. »
Угу. Вот только опять-таки, имейте в виду: первым найденным будет не то, что Вы указали — «самых чест», а «пробелсамых чес».

Или же подобные коллизии должны разруливаться на уровне настроек (учитывать/НЕучитывать пробелы или знаки конца абзаца, конца строки и т.п.; искать/НЕискать внутри найденных дубликатов; расширять/НЕрасширять выделение дубликатов на всю строку, характерную для совпадений (в моем примере до "самых честных" - опять-таки включать здесь или не включать пробел в выделение - настраивать опционально). »
Может, Вы расскажете, для каких целей сие Вам вообще потребно?

sl.oleg@fb
20-11-2016, 16:55
Цитата Iska:
Может, Вы расскажете, для каких целей сие Вам вообще потребно? »
Есть некий документ, в котором довольно неструктурно и хаосно хранятся текстовые данные, ну (для примера) кулинарные рецепты. В этот документ добавляли всяко-разно без какой-либо систематизации, т.о. рецепт "Салат оливье" может входить и два и три раза. Причем, как я писал, данные хранятся безсистемно и может быть ситуация, когда описание следующего рецепта идет не с новой строки, поэтому отсортировать строки в Excel, а потом удалить дубли его инструментами - не вариант. К тому же т.к. описания текстовые, то внутри одного рецепта может быть несколько абзацев, а значит один рецепт будет представлен несколькими строками (с точки зренеия электронных таблиц) и при этом программно определить где заканчивается один рецепт и начинается другой - невозможно - только по контексту.
Задача: почистить данный документ, удалив из него дубликаты. Чистить будем ручками, но дубли надо найти автоматически, т.к. перебирать ВСЕ названия рецептов "руками" - очень долго и хотелось бы хотя бы частично этот процесс автоматизировать. Условимся, что сами названия рецептов (целевой контекст) у нас довольно длинные и не будут конфликтовать с, например, ингредиентами рецептов, которые могут повторяться от рецепта к рецепту (потому что эти ингредиенты гораздо короче названий рецептов и будут отсеяны за счет минимальной длины строки поиска).

okshef
20-11-2016, 17:15
sl.oleg@fb, почему рубрику для названия темы вы выбрали "Разное", хотя наверняка работаете в определенной версии Word? Если она выше 2007, то при нажатии Ctrl+F слева появляется навигационная панель с результатами поиска. С ее помощью отыскать нужные фрагменты не представляет труда. Ну а удалять дубликаты, уж извольте, ручками.

sl.oleg@fb
20-11-2016, 17:35
Цитата okshef:
Ctrl+F слева появляется навигационная панель с результатами поиска. С ее помощью отыскать нужные фрагменты не представляет труда. »

Что именно вы советуете вводить в строку поиска после Ctrl-F ? Вам известно какие именно строки дублированы? И мне нет. Тогда что ж - перебирать все вручную, со сдвигом строки поиска на один символ при каждом последующем поиске? Для файла размером в 1 МБ (а у меня файлы поболе гораздо) нужно осуществить этих поисков около одного миллиона, при затрате времени на один поиск (с учетом ввода контекста и его учета) скажем 10 секунд и работе по 8 часов в день, понадобится 347 рабочих дней. А дублей в этом файле может быть 2-3 десятка, т.о. если знать какие именно данные задублированы, то файл чистится уже не в течение года, а в течение десяти минут. Разница ясна? Прочитайте пожалуйста пост внимательно (особенно то, что я повторил ниже), прежде, чем писать в него что-либо.
Цитата sl.oleg@fb:
Сами наборы символов не задаются - они программно обнаруживаются в тексте, ограничиваясь лишь их минимальной длиной. »

А версии Word на разных компах стоят разные (2007 и 2010), работать люди будут разные, поэтому привязаться к конкретной версии не представляется возможным.

Methodichka
22-11-2016, 06:38
Поиск и удаление повторяющихся фрагментов текста на русском языке, длинной от 4-х букв:
1. Диалог "Найти и заменить" (Ctrl + H).
2. Поле "Найти": ([А-ЯЁа-яё]{4;})(*)\1
3. Поле "Заменить на": \1\2
4. Кнопка "Больше" > Активируем флаг "Подстановочные знаки"

Думаю, принцип понятен. Замечу, что учитывается регистр букв.

Или вот пример для трех повторений:
Найти: ([А-ЯЁа-яё]{4;})(*)\1(*)\1
Заменить: \1\2\3

sl.oleg@fb
22-11-2016, 08:37
Ещё не пробовал, но попробую! Жесть :) , а можно ссылку на описание всей этой китайской грамоты :) , т.е. что здесь что обозначает в приведенной вами строке, как самому такие строки писать.

Я правильно понял: в вашем примере верхняя формула находит все вхождения, которые имеют дубликаты в тексте длиной не менее 2-х символов, а в нижнем - не менее 3-х символов?
Только я не понял зачем здесь что-то на что-то меняется? Мне же надо просто найти дубликаты, заменять их не надо, а что такое \1\2 ?

Попробовал, к сожалению не работает на моем примере - не находит вхождение "самых чест" (при установке {4;} в {10;}). Методом проб понял, что формула игнорирует все дубли, если в них присутствуют какие либо символы, кроме букв (напр.пробелы, подчеркивания и т.п.) :( Очень жаль. Может можно как-то доработать формулу, чтоб она искала корректно любые вхождения (с пробелами, тире, запятыми, концами абзаца и т.п.)?

Iska
22-11-2016, 09:08
Methodichka, удалять не надо. Надо просто найти примерные дубликаты «заголовков», а удаляться будут гораздо более крупные фрагменты текста. Посему не Ctrl-H, а просто Ctrl-F. Далее, к сожалению, находятся не просто повторы, а весь интервал текста между повторами (включая и сами повторы). Три повторения также бессмысленно искать по изложенным причинам.

Тем не менее, Ваша идея мне весьма нравится, и я полагаю, что пока это наиболее приемлемый вариант для полуавтоматического поиска дубликатов. Ctrl-Home, Ctrl-F, Enter — нашли, Esc, смотрим на начало выделения. Посмотрели, нажали Left, перешли в точку конца выделения (со снятием оного) и, соответственно, найденного дубликата текста. Смотрим, оцениванием, при надобности выделяем потребное, удаляем. Ctrl-Home, Ctrl-F… — ищем дальше.

а можно ссылку на описание всей этой китайской грамоты , т.е. что здесь что обозначает в приведенной вами строке, как самому такие строки писать. »
Во встроенной документации к Microsoft Office есть, идущей в комплекте. Нажимаете Ctrl-F, затем F1 и читаете, переходя по ссылкам.

Я правильно понял: в вашем примере верхняя формула находит все вхождения, которые имеют дубликаты в тексте длиной не менее 2-х символов »
Неправильно. Там же сказано — четырёх от четырёх и выше:
… длинной от 4-х букв…
2. Поле "Найти": ([А-ЯЁа-яё]{4;})(*)\1 »

а в нижнем - не менее 3-х символов? »
А в нижнем — тоже четырёх от четырёх и выше:
Найти: ([А-ЯЁа-яё]{4;})(*)\1(*)\1 »

Но нижний (поиск сразу трёх повторов) Вам и не нужен, ибо второй повтор, «средний» между первым и третьим повторами будет лежать где-то внутри выделения. Используйте первый вариант для поиска двух повторов потребной длины. Третий повтор и все последующие (четвёртый, пятый и т.д.) Вы и так найдёте при повторном поиске тех же двух повторов.

sl.oleg@fb
22-11-2016, 09:32
Испольуйте первый вариант для поиска двух повторов потребной длины. Третий повтор и все последующие (четвёртый, пятый и т.д.) Вы и так найдёте при повторном поиске тех же двух повторов. »
Я бы использовал, если б он находил все вхождения (с пробелыми, запятыми и т.д.), а так - увы... :) Поробуйте скопировать мой пример из первого поста и найти дубликат "самых чест" - ничего не получится... :(

Iska
22-11-2016, 10:27
Да, к сожалению поиск по регулярным выражениям в Word'е весьма негибкий. Подумаю, что можно придумать.

Кстати, только сейчас заметил свою ошибку: в данном случае ищется и находится не четыре, как я написал выше. Дело в том, что «;» в выражении «([А-ЯЁа-яё]{4;})(*)\1» означает «не менее». То есть будет осуществляться поиск от четырёх символов-повторов и выше — четыре, пять, шесть, …десять, … двадцать — сколько будет найдено.

Methodichka
22-11-2016, 17:56
Цитировать »
Можно и любые знаки, но такой поиск очень тормозит:
(?{10;})*\1
Вот примерчик пошустрее, для поиска цепочек от 4 до 10 знаков:
([!^13]{4;10})*\1
Но лучше указывать набор искомых знаков.

sl.oleg@fb
22-11-2016, 21:29
Но лучше указывать набор искомых знаков. »
А чем лучше-то? И как указать набор искомых знаков, в том числе таких как пробел, запятая, точка, точка с запятой, двоеточие, кавычки и скобки всех мастей и т.д.; а также конец абзаца, конец строки и т.п.

Можно и любые знаки, но такой поиск очень тормозит:
(?{10;})*\1 »

Совсем нереально использовать - просто вешает приложение и все :(

Вот примерчик пошустрее, для поиска цепочек от 4 до 10 знаков:
([!^13]{4;10})*\1 »

Все отлично работает только вот при заданой длине поиска дублей в 4-10 знаков, приходится много раз нажимать на кнопку "Далее" чтоб перейти к след.дублю, т.к. сначала он по одной букве (при каждом клике на "Далее") проходит весь первый найденный им дубль. Это можно как то поправить? И еще: не могли бы вы сбросить мне ссылку на описание символов, используемых в строке поиска?

sl.oleg@fb
22-11-2016, 22:03
Запустил поиск ([!^13]{20;25})*\1 на документе в 41 страницу уже висит крутящийся бублик минут 10... Походу использовать механизмы контекстного поиска нереально из-за их совершенной неприспособленности и неадаптированности к задачам подобного типа. Может кто-то знает программы сторонних производителей для решения таких задач? Пусть не с вордовскими файлами, а с обычными текстовыми? Лишь бы поиск дубликатов проходил в реальные сроки, хотя бы одна страница в секунду...

Methodichka
23-11-2016, 07:55
Совсем нереально использовать - просто вешает приложение и все»
Вот об этом я и говорил, когда писал, что надо указывать четкий набор знаков. Чем шире этот набор, а значит и сложнее маска поиска, тем чаще глюки Word.

Знаки перечисляются в квадратных скобках, как в примерах выше, можно через дефис: [А-ЯЁа-яё] [A-z] [0-9]

Вам надо немного освоить поиск Word. Используйте поисковики и маску "word подстановочные знаки поиск замена". К сожалению, вся справка из Word сейчас ушла на сайты Микрософт. Это радикально снизило ее качество, так как доступность справки стала никакая. И если это чувствую я как писатель макросов, то что говорить об обычных пользователях.

И не забывайте, что этот инструмент Word называется "Поиск и замена". Судя по всему, вам надо нечто большее, оригинальное. Такое реализуется уже макросами.

sl.oleg@fb
24-11-2016, 20:53
Знаки перечисляются в квадратных скобках, как в примерах выше, можно через дефис: [А-ЯЁа-яё] [A-z] [0-9] »

А как же все таки указать пробел и знак конца абзаца, но пробел особенно?

Methodichka
25-11-2016, 06:15
А как же все таки указать пробел и знак конца абзаца... »
Русский алфавит (А-ЯЁа-яё) + пробел ( ) + неразрывный пробел (^s) + знак абзаца (^13):
[А-ЯЁа-яё ^s^13]

Русский алфавит (А-ЯЁа-яё) + пробелы ( ^s) + знаки препинания (,:;\!\?):
[А-ЯЁа-яё ^s,:;\!\?]

Предыдущий пример без точки (.) потому, что то такой шаблон у мня не работает:
([А-ЯЁа-яё ^s.,:;\!\?]{4;})*\1
Похоже на очередной глюк Word.

Повторюсь :)
...надо немного освоить поиск Word... »

sl.oleg@fb
26-11-2016, 08:43
Все же поиск ворда с его глюками и тормозами - это, увы, не решение проблемы. Может все же кто-то слышал о сторонней программе, которая делает подобное с текстом?

Iska
26-11-2016, 10:42
sl.oleg@fb, мы так и не увидели даже образца с текстом, ничего не услышали про его объёмы.




© OSzone.net 2001-2012