ヘッダー
Visual Basic サンプル集
VB.NET2002対応 VB.NET2003対応 VB2005対応 VB2008対応 VB2010対応 VB2012対応 VB2013対応 VB2015対応 VB2017対応 VB2019対応 Visual Studio 2022

文字列をあいまい検索する

2021/10/24

→ C# のサンプルに切り替える

 

「源○朝」を検索する (○は任意の一文字)

VB2008対応 VB2010対応 VB2012対応 VB2013対応 VB2015対応 VB2017対応 VB2019対応 Visual Studio 2022

Dim value As String = "源実朝は源頼家の弟であり、源頼朝の子です。"
Dim results = System.Text.RegularExpressions.Regex.Matches(value, "源.{1}朝")

For Each result As System.Text.RegularExpressions.Match In results
    Debug.WriteLine($"ヒット:{result.Value} 開始位置:{result.Index}")

    '↓VB2013以前の場合
    'Debug.WriteLine("ヒット:" & result.Value & " 開始位置:" & result.Index)
Next

Debug.WriteLineが表示される場所

これを実行すると次の通りに出力されます。

ヒット:源実朝 開始位置:0
ヒット:源頼朝 開始位置:13

 

 

「源○○」を検索する (○は任意の一文字)

VB2008対応 VB2010対応 VB2012対応 VB2013対応 VB2015対応 VB2017対応 VB2019対応 Visual Studio 2022

Dim value As String = "源実朝は源頼家の弟であり、源頼朝の子です。"
Dim results = System.Text.RegularExpressions.Regex.Matches(value, "源.{2}")

For Each result As System.Text.RegularExpressions.Match In results
    Debug.WriteLine($"ヒット:{result.Value} 開始位置:{result.Index}")

    '↓VB2013以前の場合
    'Debug.WriteLine("ヒット:" & result.Value & " 開始位置:" & result.Index)
Next

Debug.WriteLineが表示される場所

これを実行すると次の通りに出力されます。

ヒット:源実朝 開始位置:0
ヒット:源頼家 開始位置:4
ヒット:源頼朝 開始位置:13

 

 

「源頼朝」以外の「源○朝」を検索する (○は任意の一文字)

VB2008対応 VB2010対応 VB2012対応 VB2013対応 VB2015対応 VB2017対応 VB2019対応 Visual Studio 2022

Dim value As String = "源実朝は源頼家の弟であり、源頼朝の子です。"
Dim results = System.Text.RegularExpressions.Regex.Matches(value, "源[^頼]{1}朝")

For Each result As System.Text.RegularExpressions.Match In results
    Debug.WriteLine($"ヒット:{result.Value} 開始位置:{result.Index}")

    '↓VB2013以前の場合
    'Debug.WriteLine("ヒット:" & result.Value & " 開始位置:" & result.Index)
Next

Debug.WriteLineが表示される場所

これを実行すると次の通りに出力されます。

ヒット:源実朝 開始位置:0

 

 

「源頼朝」以外の「源○○」を検索する (○は任意の一文字)

VB2008対応 VB2010対応 VB2012対応 VB2013対応 VB2015対応 VB2017対応 VB2019対応 Visual Studio 2022

Dim value As String = "源実朝は源頼家の弟であり、源頼朝の子です。"
Dim results = System.Text.RegularExpressions.Regex.Matches(value, "源(?!頼朝).{2}")

For Each result As System.Text.RegularExpressions.Match In results
    Debug.WriteLine($"ヒット:{result.Value} 開始位置:{result.Index}")

    '↓VB2013以前の場合
    'Debug.WriteLine("ヒット:" & result.Value & " 開始位置:" & result.Index)
Next

Debug.WriteLineが表示される場所

これを実行すると次の通りに出力されます。

ヒット:源実朝 開始位置:0
ヒット:源頼家 開始位置:4

 

 

「…ed」で終わる英単語を検索する

VB2008対応 VB2010対応 VB2012対応 VB2013対応 VB2015対応 VB2017対応 VB2019対応 Visual Studio 2022

Dim value As String = "Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure."
Dim results = System.Text.RegularExpressions.Regex.Matches(value, "(\s|^)(\w+?ed)([\s\.,]|$)")

For Each result As System.Text.RegularExpressions.Match In results
    Debug.WriteLine($"ヒット:{result.Groups(2).Value} 開始位置:{result.Groups(2).Index}")

    '↓VB2013以前の場合
    'Debug.WriteLine("ヒット:" & result.Groups(2).Value & " 開始位置:" & result.Groups(2).Index)
Next

Debug.WriteLineが表示される場所

これを実行すると次の通りに出力されます。

ヒット:engaged 開始位置:11
ヒット:conceived 開始位置:87
ヒット:dedicated 開始位置:104

メモ:正規表現の意味は次の通り。スペース(\s)または文頭(^)から開始し、文字(\w)が1つ以上(+)続き、最初の(?) ed の出現後 スペース(\s) または ピリオド(\.) または カンマ または 文末 があるもの。

メモ:正規表現に含まれる ( ) にマッチしたものは Groups() で取得できます。Groups(0)は常に正規表現にマッチした全体を表し、Groups(2)は正規表現に含まれる 2つ目の (  ) 内にマッチしたものという意味になります。

メモ:edで終わる英単語を検索するもっと簡単な正規表現があるかもしれません。

メモ:単語の区切りによってはこの例の正規表現では抽出できない場合があります。たとえば、? や ! などで単語が区切られる場合にはこの例をそのまま使用しても対応できません。

 

 

「民…法」を検索する(…は0文字以上の文字)

この例のポイントは、「民」の次に出現する「法」までを検索する必要がある点です。このために最短一致の正規表現 ? を使用します。

なぜならこの例の文字列では「法や商法の訴訟手続きは民事訴訟」が「」に合致するので、最短一致にしないと優先的にヒットしてしまうからです。最短一致を指定するかどうかは検索の要件次第です。

VB2008対応 VB2010対応 VB2012対応 VB2013対応 VB2015対応 VB2017対応 VB2019対応 Visual Studio 2022

Dim value As String = "民法や商法の訴訟手続きは民事訴訟法で定めわれている。"
Dim results = System.Text.RegularExpressions.Regex.Matches(value, "民.*?法")

For Each result As System.Text.RegularExpressions.Match In results
    Debug.WriteLine($"ヒット:{result.Value} 開始位置:{result.Index}")

    '↓VB2013以前の場合
    'Debug.WriteLine("ヒット:" & result.Value & " 開始位置:" & result.Index)
Next

Debug.WriteLineが表示される場所

これを実行すると次の通りに出力されます。

ヒット:民法 開始位置:0
ヒット:民事訴訟法 開始位置:12

メモ:"民.*?法" ではなく、"民.*法" で検索すると「民法や商法の訴訟手続きは民事訴訟法」のみヒットします。

 

 

先頭が「子」から始まる行を検索する

VB2010対応 VB2012対応 VB2013対応 VB2015対応 VB2017対応 VB2019対応 Visual Studio 2022

Dim value As String = "論語の文章は「子曰」から始まるものが多い。例を挙げてみる。" & vbCrLf &
                      "子曰學而時習之不亦説乎" & vbCrLf &
                      "子曰不患人之不己知" & vbCrLf &
                      "この「子曰」は「孔子はおっしゃった」という意味なので、" & vbCrLf &
                      "孔子以外の人物の発言は次のように当然異なる書き出しとなる。" & vbCrLf &
                      "子貢問曰貧而無諂富而無驕何如"
Dim results = System.Text.RegularExpressions.Regex.Matches(value, "^(子.*?)(\r|\n)", 
                                           System.Text.RegularExpressions.RegexOptions.Multiline)

For Each result As System.Text.RegularExpressions.Match In results
    '全体でのヒットした位置。ここでは改行も1文字または2文字とカウントします。
    Dim index As Integer = result.Groups(1).Index
    'その位置までの改行。
    Dim linebreaks = System.Text.RegularExpressions.Regex.Matches(value.Substring(0, index), "(\r\n|\n)")
    'その位置が何行目か。(行数はそこまでの改行の数+1)
    Dim row As Integer = linebreaks.Count + 1

    Debug.WriteLine($"ヒット:{result.Groups(1).Value} 開始位置:{index} {row}行目")

    '↓VB2013以前の場合
    'Debug.WriteLine("ヒット:" & result.Groups(1).Value & " 開始位置:" & index & " " & row & "行目")
Next

Debug.WriteLineが表示される場所

これを実行すると次の通りに出力されます。

ヒット:子曰學而時習之不亦説乎 開始位置:31 2行目
ヒット:子曰不患人之不己知 開始位置:44 3行目

メモ:正規表現の意味は次の通り。行頭(^)の直後に「子」があり、文字(.)が0個以上続き(*)、その後の最初の(?)改行(\rまたは\n)まで

メモ:正規表現に含まれる ( ) にマッチしたものは Groups() で取得できます。Groups(0)は常に正規表現にマッチした全体を表し、Groups(1)は正規表現に含まれる 1つ目の (  ) 内にマッチしたものという意味になります。

 

 

末尾が「る。」で終わる行を検索する

VB2010対応 VB2012対応 VB2013対応 VB2015対応 VB2017対応 VB2019対応 Visual Studio 2022

Dim value As String = "論語の文章は「子曰」から始まるものが多い。例を挙げてみる。" & vbCrLf &
                      "子曰學而時習之不亦説乎" & vbCrLf &
                      "子曰不患人之不己知" & vbCrLf &
                      "この「子曰」は「孔子はおっしゃった」という意味なので、" & vbCrLf &
                      "孔子以外の人物の発言は次のように当然異なる書き出しとなる。" & vbCrLf &
                      "子貢問曰貧而無諂富而無驕何如"
Dim results = System.Text.RegularExpressions.Regex.Matches(value, "^(.*る。)(\r|\n)", 
                                           System.Text.RegularExpressions.RegexOptions.Multiline)

For Each result As System.Text.RegularExpressions.Match In results
    '全体でのヒットした位置。ここでは改行も1文字または2文字とカウントします。
    Dim index As Integer = result.Groups(1).Index
    'その位置までの改行。
    Dim linebreaks = System.Text.RegularExpressions.Regex.Matches(value.Substring(0, index), "(\r\n|\n)")
    'その位置が何行目か。(行数はそこまでの改行の数+1)
    Dim row As Integer = linebreaks.Count + 1

    Debug.WriteLine($"ヒット:{result.Groups(1).Value} 開始位置:{index} {row}行目")

    '↓VB2013以前の場合
    'Debug.WriteLine("ヒット:" & result.Groups(1).Value & " 開始位置:" & index & " " & row & "行目")
Next

Debug.WriteLineが表示される場所

これを実行すると次の通りに出力されます。

ヒット:論語の文章は「子曰」から始まるものが多い。例を挙げてみる。 開始位置:0 1行目
ヒット:孔子以外の人物の発言は次のように当然異なる書き出しとなる。 開始位置:84 5行目

メモ:正規表現の意味は次の通り。行頭(^)から文字(.)が0個以上続き(*)、その後に「る。」と改行(\rまたは\n)が連続する

メモ:正規表現に含まれる ( ) にマッチしたものは Groups() で取得できます。Groups(0)は常に正規表現にマッチした全体を表し、Groups(1)は正規表現に含まれる 1つ目の (  ) 内にマッチしたものという意味になります。

 

 


VB6対応 VB6ではMicrosoft VBScript Regular Expressionsに参照設定をすれば正規表現を使用できます。