Как сделать правильный поиск по ключевым словам - PullRequest
0 голосов
/ 06 мая 2019

Если я ищу термин 'tfo' в значении ячейки 'TFO_xyz', то результат должен быть ИСТИНА.Если я ищу термин «tfo» в значении ячейки «TFO systems», то результат должен быть ИСТИНА.

Если я ищу термин «tfo» в значении ячейки «spring TFO», то результатдолжно быть ИСТИНА.

НО, если я проверю 'tfo' в значении ячейки 'Платформа', тогда я хочу получить результат как ЛОЖЬ

Я использовал формулу =IF(COUNTIF(A2,"*tfo*"),"TRUE","FALSE"), но это не дастрезультат «ЛОЖЬ», когда я проверяю «tfo» в слове «Платформа»

ПРИМЕЧАНИЕ:

Платформа должна быть ложной, поскольку между словом стоит tfo.Я смотрю результат как True для значений ячеек только со словом tfo, как в tfo <‌space> America или TFO_America или <‌space> TFO.Но я хочу получить ЛОЖНЫЙ результат для слов Платформа и портфель, потому что в этих двух словах термин tfo находится между алфавитами.

Ответы [ 6 ]

0 голосов
/ 07 мая 2019

Если вы можете положиться на VBA, то регулярное выражение является более гибким решением.

Существует хорошее краткое изложение того, как использовать их в VBA: Как использовать регулярные выражения (Regex) в Microsoft Excel как внутри ячейки, так и в циклах

Для вашей проблемы поиска по ключевым словам я написал следующее:

Option Explicit

' Include: Tools > References > Microsoft VBScript Regular Expressions 5.5 (C:\Windows\SysWOW64\vbscript.dll\3)


Public Function SearchKeyWord(strHay As String, strNail As String, Optional strDelimiters As String = " _,.;/", Optional lngNthOccurrence As Long = 1) As Long ' Returns 1-based index of nth occurrence or 0 if not found
    Dim strPattern As String: strPattern = CreatePattern(strNail, strDelimiters)
    Dim rgxKeyWord As RegExp: Set rgxKeyWord = CreateRegex(strPattern, True)
    Dim mtcResult As MatchCollection: Set mtcResult = rgxKeyWord.Execute(strHay)
    If (0 <= lngNthOccurrence - 1) And (lngNthOccurrence - 1 < mtcResult.Count) Then
        Dim mthResult As Match: Set mthResult = mtcResult(lngNthOccurrence - 1)
        SearchKeyWord = mthResult.FirstIndex + Len(mthResult.SubMatches(0)) + 1
    Else
        SearchKeyWord = 0
    End If
End Function

Private Function CreateRegex(strPattern As String, Optional blnIgnoreCase As Boolean = False, Optional blnMultiLine As Boolean = True, Optional blnGlobal As Boolean = True) As RegExp
    Dim rgxResult As RegExp: Set rgxResult = New RegExp
    With rgxResult
        .Pattern = strPattern
        .IgnoreCase = blnIgnoreCase
        .MultiLine = blnMultiLine
        .Global = blnGlobal
    End With
    Set CreateRegex = rgxResult
End Function

Private Function CreatePattern(strNail As String, strDelimiters As String) As String
    Dim strDelimitersEscaped As String: strDelimitersEscaped = RegexEscape(strDelimiters)
    Dim strPattern As String: strPattern = "(^|[" & strDelimitersEscaped & "]+)(" & RegexEscape(strNail) & ")($|[" & strDelimitersEscaped & "]+)"
    CreatePattern = strPattern
End Function

Private Function RegexEscape(strOriginal As String) As String
    Dim strEscaped As String: strEscaped = vbNullString
    Dim i As Long: For i = 1 To Len(strOriginal)
        Dim strChar As String: strChar = Mid(strOriginal, i, 1)
        Select Case strChar
        Case ".", "$", "^", "{", "[", "(", "|", ")", "*", "+", "?", "\"
            strEscaped = strEscaped & "\" & strChar
        Case Else
            strEscaped = strEscaped & strChar
        End Select
    Next i
    RegexEscape = strEscaped
End Function

Если у вас есть все вышеперечисленное в модуле, вы можете вставить следующие формулы:

=SearchKeyWord($A1,"tfo")

, где A1 содержит, например, "Америка".

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

Возвращаемое значение - это позиция n-го вхождения ключевого слова, где n - это значение четвертого параметра (по умолчанию: 1) или 0, если не найдено.

Чтобы проверить, присутствует ли ключевое слово в A1, сравните результат с 0, что означает, что он не найден:

=--(SearchKeyWord($A1,"tfo")<>0)
0 голосов
/ 06 мая 2019

Я предлагаю потратить некоторое время, чтобы узнать ваши данные и создать белый список. Поскольку нет простого способа сделать нечеткий поиск в строках.

Function TFO_Search(strText As String) As Boolean

Dim ArryString      As Variant
Dim ArryWhitelist   As Variant

' Create a White-List Array
ArryWhitelist = Array("TFO_", "TFO ", "_TFO", " TFO", "tfoAmerica")

For Each ArryString In ArryWhitelist
If InStr(UCase(strText), UCase(ArryString)) > 0 Then  'force to UPPER CASE
    TFO_Search = True
    Exit Function
Else
    TFO_Search = False
End If
Next

End Function
0 голосов
/ 06 мая 2019

Эта формула вернет true, если TFO находится в начале или конце любого данного слова или само по себе в текстовой строке. Он также проверяет каждое слово в текстовой строке, поэтому TFO может быть в начале, в середине или в конце. Формула предполагает, что если слово начинается или заканчивается TFO, то результатом должно быть ИСТИНА (как в случае tfoAmerica, поэтому то же правило будет применяться к tform), иначе FALSE.

=OR(ISNUMBER(SEARCH({" tfo","tfo "}," "&SUBSTITUTE(A2,"_"," ")&" ")))

Вот его результаты:

enter image description here

EDIT

В случае, если результат должен быть ИСТИННЫМ, только если TFO найден сам по себе, тогда этой версии формулы будет достаточно:

=ISNUMBER(SEARCH(" tfo "," "&SUBSTITUTE(A2,"_"," ")&" "))

Изображение, показывающее результаты второй версии:

enter image description here

0 голосов
/ 06 мая 2019

Попробуйте эту формулу.Это предполагает, что слово tfo будет в начале или в конце. Просто убедитесь, что поместили соответствующие имена ячеек, где у меня есть 'A2' в формуле

=IF(OR(PROPER(LEFT(A2,3))="tfo",PROPER(RIGHT(A2,3))="tfo"),TRUE,FALSE)

Тестовые случаи ниже:

enter image description here

0 голосов
/ 06 мая 2019

Я вижу два аспекта сложности в вашем вопросе:

  • Где ключевое слово встречается в тексте (начало, середина, конец)
  • Какие символы разделяют слова.

Первый - фиксированный размер, вам нужно обработать три случая. Второй зависит от количества символов, которые вы хотите принять в качестве разделителей. Ниже я предположил, что вы принимаете пробел и подчеркивание, однако вы можете расширить этот набор, вставив больше SUBSTITUTE вызовов функций.

В моей таблице $ A2 - это ячейка, в которой вы ищете ключевое слово, а B $ 1 содержит ключевое слово.

Чтобы стандартизировать символ-разделитель, вам нужна формула:

B2=SUBSTITUTE($A2,"_"," ")

Чтобы проверить, начинается ли строка с ключевого слова:

C2=--(LEFT($B2,LEN(B$1)+1)=B$1&" ")

Чтобы проверить, заканчивается ли строка ключевым словом:

D2=--(RIGHT($B2,LEN(B$1)+1)=" "&B$1)

Чтобы проверить, находится ли ключевое слово в середине строки:

E2=--(LEN(SUBSTITUTE(UPPER($B2)," "&UPPER(B$1)&" ",""))<LEN($B2))

Для оценки трех приведенных выше случаев:

F2=--(0<$C2+$D2+$E2)

Если вы хотите использовать одну ячейку, объедините формулы в:

G2=--(0<--(LEFT(SUBSTITUTE($A2,"_"," "),LEN(B$1)+1)=B$1&" ")+--(RIGHT(SUBSTITUTE($A2,"_"," "),LEN(B$1)+1)=" "&B$1)+--(LEN(SUBSTITUTE(UPPER(SUBSTITUTE($A2,"_"," "))," "&UPPER(B$1)&" ",""))<LEN(SUBSTITUTE($A2,"_"," "))))

В конце концов, он не очень читабелен, но я не думаю, что было более простое решение с использованием только формул.

Примечание. Если вы хотите изменить набор символов, принимаемых в качестве разделителей, добавьте еще вызовы функций SUBSTITUTE в B2, затем скопируйте формулу F2 в блокнот и замените $ C2 формулой C2 и т. Д., Затем замените $ B2 на обновленную формулу B2.

Обновление

Опираясь на идею в комментарии Рона Розенфельда к ответу tigeravatar, формулу можно упростить (можно объединить начало, середину, конец):

=--(LEN(SUBSTITUTE(" "&UPPER($B2)&" "," "&UPPER(B$1)&" ",""))<LEN($B2))

После подстановки $ B2 в формулу:

=--(LEN(SUBSTITUTE(" "&UPPER(SUBSTITUTE($A2,"_"," "))&" "," "&UPPER(B$1)&" ",""))<LEN(SUBSTITUTE($A2,"_"," ")))
0 голосов
/ 06 мая 2019

Попробуйте это:

Dim x As Long: x = 1

With Sheet1

    Do While x <= .Cells(.Rows.Count, 1).End(xlUp).Row

        If VBA.Left(.Cells(x, 1).Value, 3) = "tfo" Or VBA.Right(.Cells(x, 1).Value, 3) = "tfo" Then

            .Cells(x, 2).Value = True

        End If

        x = x + 1

    Loop

End With
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...