Редактировать 1 - решение
Используя шаблон, приведенный ниже в качестве начала, я немного отредактировал выражение, чтобы убедиться, что оно содержит фразы и слова, а затем мы просто отбрасываем любое совпадение, начинающееся с .
Sub test()
Application.EnableEvents = False
getAllTitleCasePhrases Range("D4", Range("D4").End(xlDown))
Application.EnableEvents = True
End Sub
Private Sub getAllTitleCasePhrases(rng As Range)
If objRegex Is Nothing Then Set objRegex = New RegExp
With objRegex
.Global = True
.Pattern = "(\.\s*[A-Z][\w,']*)|([A-Z][\w,']*\s?)+"
End With
Dim cll As Range, testResult As Object, resultsStr As String
For Each cll In rng
Set testResult = objRegex.Execute(cll.Value2)
If testResult.Count > 0 Then
Dim i As Long, j As Long
For i = 0 To testResult.Count - 1
If Left$(testResult(i), 1) <> "." Then
resultsStr = resultsStr & WorksheetFunction.Trim(testResult(i).Value) & ", "
End If
Next i
End If
If Len(resultsStr) > 0 Then resultsStr = Left(resultsStr, Len(resultsStr) - 2)
cll.Offset(0, 1).Value2 = resultsStr
resultsStr = vbNullString
Next cll
Set objRegex = Nothing
End Sub
Задача
Я хотел бы автоматически создать список всех определенных терминов в контракте, чтобы затем я мог легко проверить, действительно ли они где-то имеют соответствующее определение. Определенные условия в контракте написаны либо в «Заголовке дела», либо во ВСЕХ КАПИЯХ, я включил несколько тестовых случаев и ожидаемый результат ниже.
Мой подход заключается в использовании шаблона регулярных выражений для сканирования документа и выделения всех слов или фраз, которые соответствуют этим шаблонам. Эта часть была проста, используя ответы здесь и здесь . Проблемы, с которыми я столкнулся, заключаются в том, что (1) он по-прежнему ловит слова, которые пишутся с заглавной буквы после полной остановки, и (2) пробел в конце последнего слова включается в совпадение.
Пожалуйста, обратите внимание, что моя реализация ниже в Excel VBA, но это выражение регулярного выражения, которое меня действительно интересует. Если оба (1) и (2) не могут быть достигнуты вместе, (1) важнее, так как я могу удалить конечные пробелы в другом месте кода.
Текущее решение
(^[^\.])?([A-Z]+[a-z,']*\s?)+
Пояснение:
(^[^\.])?
- если в начале строки есть полный останов, игнорируйте ее
[A-Z]+
- сопоставить слова, начинающиеся хотя бы с одной заглавной буквы
[a-z,']*
- слова могут заканчиваться любым количеством не прописных, допускается апостроф
([A-Z]+[a-z,']*\s?)+
- повторите этот шаблон, чтобы поймать несколько слов
Контрольные примеры
- Сравнить -> Сравнить
- Сравнить -> Сравнить
- для сравнения -> Сравнить между
- СРАВНИТЬ МЕЖДУ -> СРАВНИТЬ МЕЖДУ
- для сравнения двух вариантов -> Сравнение между двумя параметрами
- Покупатель обязан -> Покупатель
- Покупатель должен оплатить в срок в соответствии с согласованным графиком
между Сторонами -> Покупатель, Оплата в срок, График, Стороны
- . Покупатель оплачивает в срок в соответствии с согласованным графиком
между Сторонами -> Покупатель, Оплата в срок, График, Стороны
- Покупатель -> Покупатель
- . Покупатель -> Покупатель
- . СРАВНИТЬ -> СРАВНИТЬ
- Представитель Покупателя -> Представитель Покупателя
- Представитель покупателя -> Представитель покупателя
- Представитель покупателя -> Представитель покупателя
- . Представитель Покупателя -> Представитель Покупателя
- ACME International group -> ACME International
- ACME International Group -> ACME International Group
- ABC -> ABC
Осуществление
(обратите внимание, что список тестов начинается с ячейки D4
)
Option Explicit
Private objRegex As RegExp
Sub test()
getAllTitleCasePhrases Range("D4", Range("D4").End(xlDown))
End Sub
Private Sub getAllTitleCasePhrases(rng As Range)
If objRegex Is Nothing Then Set objRegex = New RegExp
With objRegex
.Global = True
.Pattern = "(^[^\.])?([A-Z]+[a-z,']*\s?)+"
End With
Dim cll As Range, testResult As Object, resultsStr As String
For Each cll In rng
Set testResult = objRegex.Execute(cll.Value2)
If testResult.Count > 0 Then
Dim i As Long
For i = 0 To testResult.Count - 1
resultsStr = resultsStr & testResult(i).Value & ", "
Next i
End If
If Len(resultsStr) > 0 Then resultsStr = Left(resultsStr, Len(resultsStr) - 2)
cll.Offset(0, 1).Value2 = resultsStr
resultsStr = vbNullString
Next cll
Set objRegex = Nothing
End Sub