2017-02-12 10 views
1

私は、文字列内の単語を検索する次の関数を持っています。例えば、donを検索すると、donが見つかり、それは私が望むものではありません。 "私はDonを知らないのですか?文字列内の単語を検索するExcel VBA関数でワイルドカード*を使用するにはどうすればよいですか?

私はまた、私はレース、レース、レースのような言葉を探す必要があることを知っています。私はrac *を検索して、そのようなバリアントをすべて検索するのではなく、そのようなバリアントをすべてカバーできるようにしたいと考えています。

これを行うにはコードを更新することはできますか?あるいは誰かがこの問題を解決できるコードを持っていますか?私は次のように行くと思い

Function InStrExact(Start As Long, SourceText As String, WordToFind As String, _ 
    Optional CaseSensitive As Boolean = False) 

    Dim x As Long, Str1 As String, Str2 As String, Pattern As String 

    If CaseSensitive Then 
    Str1 = SourceText 
    Str2 = WordToFind 
    Pattern = "[!A-Za-z0-9]" 
    Else 
    Str1 = UCase(SourceText) 
    Str2 = UCase(WordToFind) 
    Pattern = "[!A-Z0-9]" 
    End If 

    For x = Start To Len(Str1) - Len(Str2) + 1 
    If Mid(" " & Str1 & " ", x, Len(Str2) + 2) Like Pattern & Str2 & Pattern _ 
     And Not Mid(Str1, x) Like Str2 & "'[" & Mid(Pattern, 3) & "*" Then 
     InStrExact = x 
     Exit Function 
    End If 
    Next 
End Function 
+2

パターンマッチングが複雑になるにつれて、正規表現を学習して使用すると、より便利で柔軟なツールになることがあります。 [VBAの正規表現の使い方](http://stackoverflow.com/questions/22542834/how-to-use-regular-expressions-regex-in-microsoft-excel-both-in-cell-and-loops) –

+1

@Delについて*「私はドンの友人です」*?この場合、あなたのコードは* "Don" *にマッチしますか? –

答えて

0

簡単な修正は、元の文字列の残りのすべての文字に対して、検索文字列と一致するの末尾にワイルドカードを追加することです。これで

If Mid(" " & Str1 & " ", x, Len(Str2) + 2) Like Pattern & Str2 & Pattern _ 

If Mid(" " & Str1 & " ", x) Like Pattern & Str2 & Pattern & "*" _ 

これは単純にマッチする文字の数の制限を削除変更は、この行を交換することです。ワイルドカードが検索語の末尾に追加された場合は、末尾のパターンの前に来るので、任意の数の追加文字を許可します。検索語にワイルドカードがない場合、後続パターンは依然として検索語の直後に来る必要があり、したがって完全一致を必要とする。

検索している単語が最後の単語で、ワイルドカードを追加すると問題が発生することに注意してください。 Str2の長さは、関数が早すぎる検索を停止する原因となります。これで

For x = Start To Len(Str1) - Len(Str2) + 1 

For x = Start To Len(Str1) 

以前のチェックを停止する必要はありませんので、完全なソリューションは、この行を交換することです。

+0

マイケルのように働いた - ありがとう! 誰もが答えを下降させているのかどうかはわかりません。 – Del

0

は次のとおりです。

Function InStrExact(startPos As Long, sourceText As String, wordToFind As String, _ 
        Optional CaseSensitive As Boolean = False) As Long 

    Dim x As Long 
    Dim actualSourceText As String, actualWordToFind As String, Pattern As String 
    Dim word As Variant 

    actualSourceText = Replace(Mid(sourceText, startPos), ",", "") 
    If CaseSensitive Then 
     Pattern = "[A-za-z]" 
    Else 
     actualSourceText = UCase(actualSourceText) 
     actualWordToFind = UCase(wordToFind) 
     Pattern = "[A-Z]" 
    End If 

    For Each word In Split(actualSourceText, " ") 
     If CStr(word) Like actualWordToFind & Pattern Or CStr(word) = actualWordToFind Then 
      InStrExact2 = x + 1 
      Exit Function 
     End If 
     x = x + Len(word) + 1 
    Next 
    InStrExact = -1 '<--| return -1 if no match 
End Function 
+0

ありがとう、これはありがたいことです - wordtofindは句になる可能性がありますので、これは単一の単語だけを検索するため動作しません。 – Del

+0

あなたの質問には一言だけの例しか書いていません。だからあなたは少なくともdownvoteを削除することがあります! – user3598756

+0

私の間違い。私はそれをopで言及すべきだった。 私はそれを投票しなかった - 誰がしたのかわからない...私は投票を追加しました。私は参照してください。 – Del

関連する問題