Подстановочные знаки VBA Word - поиск кратчайшего набора символов

У меня проблемы с поиском рабочего решения уже пару часов. Надеюсь, вы мне поможете.

Моя проблема: мне нужно найти и выбрать в Word целое предложение после указания начальной и конечной строк конкретного предложения. Например, если моя начальная строка — «Люди», а конечная — «яблоки». Я ожидаю, что Word выберет все «Люди любят красные яблоки». предложение в моем документе. (Если такое предложение существует)

Для этого я подготовил макрос, который работает почти так, как я хочу. Единственная проблема заключается в том, что он не выбирает наименьший возможный набор символов (что я и хочу сделать). Чтобы было понятно, предположим, что в моем документе есть этот текст: People like smoking. People like red apples.

Теперь, когда я предоставляю макросу начальную и конечную строки соответственно как «Люди» и «яблоки», он выбирает весь текст, который содержит 2 предложения, упомянутые выше. В этом моя проблема: я хотел, чтобы было выбрано только второе предложение (People like red apples.), а не оба, даже если они начинаются с одного и того же слова. Так что, по сути, я всегда хочу выбрать максимально короткий набор символов (в данном случае это только последнее предложение).

Вот часть моего макроса в VBA:

`text_str = startStr & "*" & endStr

With Application.Selection.Find
    .ClearFormatting 
        .Forward = True         
        .Wrap = wdFindContinue  
        .Text = text_str 
        .MatchWildcards = True
        .MatchCase = True       
        .Execute
End With

Я знаю, что проблема связана с подстановочными знаками (или очень ограниченным набором регулярных выражений), поэтому я также попробовал что-то вроде этого в качестве строки поиска:

text_str = "(" & startStr & "*){1}" & endStr

Тоже не помогло. Я застрял здесь. :/

Спасибо за любые предложения!


person puchat    schedule 01.08.2017    source источник
comment
Что делать, если вы используете startStr & "[!?\!.]*" & endStr? Однако startStr будет соответствовать в любом месте предложения, не обязательно в начале.   -  person Wiktor Stribiżew    schedule 01.08.2017
comment
Хорошо, извините, я ошибся, копируя ваше предложение. В VBA нет ошибки, но работает точно так же, как и в моем решении. :(   -  person puchat    schedule 01.08.2017
comment
Какая версия MS Office?   -  person Wiktor Stribiżew    schedule 01.08.2017
comment
Я использую MS Office 2013. Я отредактировал свой предыдущий комментарий, очень прошу прощения за то, что ввел вас в заблуждение. Это работает, но точно так же, как и мои идеи (выбирает оба предложения, а не только последнее).   -  person puchat    schedule 01.08.2017
comment
Я был бы очень признателен за любые другие предложения, чтобы заставить его наконец работать так, как я хочу. :)   -  person puchat    schedule 01.08.2017
comment
Хорошо, я вспомнил. В MS Word невозможно сопоставить 0 символов с подстановочным знаком. Таким образом, вы можете использовать только startStr & "[!?\!.]@" & endStr. В противном случае вам понадобится регулярное выражение.   -  person Wiktor Stribiżew    schedule 01.08.2017
comment
О, спасибо, это работает в примере, который я привел выше. Но есть еще один аспект, что я не всегда хочу искать ровно одно предложение, указав начало и конец, иногда это два или более предложений. Просто добавьте к моему первому примеру это предложение в конце: Я был в школе вчера.. Теперь, если я предоставлю Люди и вчера. соответственно, как начальная и конечная строки, ничего не выбирается... (и я хотел найти и выбрать два последних предложения) :( Можете ли вы мне помочь? Даже если мне придется использовать регулярные выражения. Это действительно важно для меня.   -  person puchat    schedule 01.08.2017


Ответы (1)


Selection.Find имеет что-то похожее на регулярные выражения, но в этом случае вы должны использовать настоящие регулярные выражения.

Шаблон (в данном конкретном случае) должен быть:

People[^.]+apples\.

Я написал пример макроса, который:

  1. Выделяет весь текст в документе и присваивает его переменной src (искомой по регулярному выражению).
  2. Устанавливает курсор в начало документа.
  3. Проверяет, можно ли сопоставить шаблон (regEx.Test).
  4. Выполняет регулярное выражение.
  5. Присваивает совпадающую строку переменной ret.
  6. Отображает его в окне сообщения.

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

Sub Re()
  Dim startStr As String: startStr = "People"
  Dim endStr As String: endStr = "apples"
  Dim pattern As String: pattern = startStr & "[^.]+" & endStr & "\."
  Dim regEx As New RegExp
  Dim src As String
  Dim ret As String
  Dim colMatches As MatchCollection

  ActiveDocument.Range.Select
  src = ActiveDocument.Range.Text
  Selection.StartOf
  regEx.pattern = pattern
  If (regEx.Test(src)) Then
    Set colMatches = regEx.Execute(src)
    ret = "Match: " & colMatches(0).Value
  Else
    ret = "Matching Failed"
  End If
  MsgBox ret, vbOKOnly, "Result"
End Sub
person Valdi_Bo    schedule 01.08.2017
comment
Большое спасибо за ваши усилия! :) Да, в приведенном мной примере это работает хорошо. Но, пожалуйста, прочитайте мой последний комментарий в предыдущем посте. Иногда мне это нужно, чтобы выбрать два или более предложений, поэтому в этом случае я не могу исключить символ точки в шаблоне. :( Более того, я не всегда хочу выделять ровно одно предложение, иногда я хочу выделить часть текста, которая начинается и заканчивается определенным образом. Рассмотрим этот пример: в Word у нас есть текст apple orange peach grape orange fruit chocolate, и теперь я хочу выделить < b>только часть от второго апельсина до конца шоколада. - person puchat; 02.08.2017
comment
... Итак, я хочу выбрать точно orange fruit chocolate, указав оранжевый цвет в качестве начальной строки и шоколад в качестве конечной строки. Как вы знаете, текущий шаблон не будет работать должным образом, он будет выделять часть orange peach grape orange fruit chocolate из текста, поэтому, как вы видите, он содержит лишние символы в начале, которых я не хочу. Можете ли вы помочь мне найти лучший шаблон для решения этой проблемы? Мне очень трудно найти рабочее решение. Но в любом случае большое спасибо за ответ! Я обязательно воспользуюсь, но мне нужно настроить выкройку. - person puchat; 02.08.2017