Я пытаюсь найти текст в Word 2010 в следующем формате: ABC.DEF.XYZ. По сути, это поиск ссылок на код с использованием синтаксиса Java, записанных в документ Word. Обратите внимание, что ссылка из 3 элементов — это всего лишь пример. Фактические ссылки содержат минимум 2 и максимум 5 элементов.
Я перепробовал множество комбинаций с подстановочными знаками (и без них), чтобы это заработало, но безуспешно. Вот некоторые из вещей, которые я пробовал:
<([a-z0-9A-Z]@)>.<([a-z0-9A-Z]@)>
ПРИМЕЧАНИЕ, это на самом деле работает для поиска ссылки из 2 элементов. Это было либо удачно, либо неудачно при поиске шаблона в более длинной строке (например, сопоставление элементов 2 и 3 ссылки из 3 элементов)<([a-z0-9A-Z]@)>(.<([a-z0-9A-Z]@)>)@
Выдает ошибку - неверный шаблон<([a-z0-9A-Z]@)>.<([a-z0-9A-Z]@)>.<([a-z0-9A-Z]@)>
Работает так долго, что Word завис более чем на 15 минут и не нашел ни одного совпадения (документ содержит около 150 страниц текста, так что, возможно, он просто не смог его обработать)<([a-z0-9A-Z]@)>.<([a-z0-9A-Z]@)>.<([a-z0-9A-Z]@)>.<([a-z0-9A-Z]@)>
Word действительно завис, когда я попробовал это сделать.
В идеале, я думаю, рабочая версия #2 была бы идеальной, однако я не знаю, как сделать шаблон действительным.
Если это невозможно, я мог бы просто использовать #1 и надеяться, что он поймает все (не уверен, почему он соответствует определенным строкам и не соответствует другим).
Любая помощь будет высоко оценена.
решение1
Вместо поиска по подстановочным знакам Word можно использовать движок VBA RegEx.
Итак, задача состояла в том, чтобы найти все строки со следующим шаблоном
###.###
###.###.###
###.###.###.###
###.###.###.###.###
Лучший узор, который я смог создать, был
([\w\d]{3}\.){1,4}[\w\d]{3}
который возвращает следующие совпадения, отмеченные желтым
Объяснение шаблона
\w
соответствует одному символу из Az. Регистр не учитывается.\d
соответствует цифре 0-9[\w\d]{3}
соответствует 3 символам или цифрам, напримерABC
,abc
,123
, ,Ab1
-, но неA$C
илиABCD
([\w\d]{3}\.){1,4}
соответствует 1,2,3 или 4 группам со следующим пунктом\.
. Последняя группа[\w\d]{3}
не запрашивает следующий пункт
VBA-макрос
Нажмите ALT+, F11чтобы открыть редактор VBA. Вставьте код в любое место и выполните его с помощьюF5
Sub RegExMark()
Dim RegEx As Object
Set RegEx = CreateObject("VBScript.RegExp")
RegEx.Global = True
RegEx.Pattern = "([\w\d]{3}\.){1,4}[\w\d]{3}"
Set Matches = RegEx.Execute(ActiveDocument.Range)
For Each hit In Matches
Debug.Print hit
ActiveDocument.Range(hit.FirstIndex, hit.FirstIndex + hit.Length). _
HighlightColorIndex = wdYellow
Next hit
End Sub
Предостережение
Как отмечено красным на изображении примера, текущий шаблон имеет изъян и также соответствует подстрокам строк, которые слишком длинные. Я немного поигрался с \b
, [^\.]
но \s
ни один из них не сработал для каждого случая. Может быть, другие пользователи найдут подходящее решение?
Использованные ресурсы
решение2
Я бы посоветовал скопировать текст в Notepad++, а затем использовать опцию RegEx для внесения изменений.
Я знаю, это звучит утомительно, но как только вы привыкнете, вы сможете очень быстро переключаться между программами.
RegEx — это опция в окне «Найти/Заменить» в Notepad++. В других редакторах есть такая же функция.
Иван
решение3
Если вам действительно нужно использовать метод поиска объекта range в Word, я думаю, вам понадобится несколько проходов по тексту, каждый раз используя один из следующих подстановочных знаков поиска:
[!.a-z0-9A-Z]([a-z0-9A-Z]@).([a-z0-9A-Z]@)[!.a-z0-9A-Z]
[!.a-z0-9A-Z]([a-z0-9A-Z]@).([a-z0-9A-Z]@)[.][!a-z0-9A-Z]
[!.a-z0-9A-Z]([a-z0-9A-Z]@).([a-z0-9A-Z]@).([a-z0-9A-Z]@)[!.a-z0-9A-Z]
[!.a-z0-9A-Z]([a-z0-9A-Z]@).([a-z0-9A-Z]@).([a-z0-9A-Z]@)[.][!a-z0-9A-Z]
[!.a-z0-9A-Z]([a-z0-9A-Z]@).([a-z0-9A-Z]@).([a-z0-9A-Z]@).([a-z0-9A-Z]@) [!.a-z0-9A-Z]
[!.a-z0-9A-Z]([a-z0-9A-Z]@).([a-z0-9A-Z]@).([a-z0-9A-Z]@).([a-z0-9A-Z]@)[.][!a-z0-9A-Z]
[!.a-z0-9A-Z]([a-z0-9A-Z]@).([a-z0-9A-Z]@).([a-z0-9A-Z]@).([a-z0-9A-Z]@).([a-z0-9A-Z]@)[!.a-z0-9A-Z]
[!.a-z0-9A-Z]([a-z0-9A-Z]@).([a-z0-9A-Z]@).([a-z0-9A-Z]@).([a-z0-9A-Z]@).([a-z0-9A-Z]@)[.][!a-z0-9A-Z]
Первая из каждой группы найдет ver #, за которым следует не точка или буква-номер. Вторая найдет ver#, который заканчивается точкой, например, конец предложения.
Эти подстановочные знаки найдут выборку, начиная с символа перед номером версии и до 2 символов после номера версии. Однако подгруппы будут извлечены и назначены нормально.
Здесь есть 2 проблемы с использованием метода поиска слова с использованием подстановочных знаков. Одна из них заключается в том, что слово не имеет способа указать 0 или более определенного символа или группы одинаковых символов. Это исключает некоторые простые методы сопоставления, которые могут быть обработаны функцией regex.
Вторая проблема заключается в том, что точка внутри ver # выглядит как конец слова, поэтому угловые скобки излишни по сравнению с использованием точки в подстановочном знаке. Угловые скобки также не следует использовать снаружи, поскольку это приводит к ложному совпадению, когда ver # с небольшим количеством подгрупп находится внутри строки с большим количеством подгрупп.
Мне также нужно добавить, что если вы выполняете "find", а затем "replace", вам следует изменить выборку, возвращаемую выполнением "find", чтобы ее конец был равен концу документа (надеюсь, вы ранее сохранили это значение). Это связано с тем, что команда replace не найдет снова соответствующую выборку, если выборка равна тексту "find". Я знаю, что это верно для поиска/замены без подстановочных знаков. Лучше перестраховаться, чем потом сожалеть.