.NET Core 3.0以降のGroupCollectionは、IReadOnlyDictionary<string, Group>インターフェイスも実装しています。 これにしたがって、GroupCollectionをディクショナリとして扱えるほか、グループ・名前付きグループをKeyValuePair<string, Group>として取得することができます。
上記の結果にも現れているように、IReadOnlyDictionary<string, Group>を介したアクセスの場合、名前なし・名前付きに関わらずグループ化された部分が列挙されます。 また、名前なしのグループでは、グループ番号は文字列のキーとして列挙され、マッチ箇所全体を表すグループとして"0"
が常に含まれます。
このほかにもGroupCollectionでIReadOnlyDictionary由来のメソッド・プロパティとして、Keysプロパティ・ContainsKeyメソッド・TryGetValueメソッドを使うこともできます。 これらのメソッド・プロパティは、正規表現にマッチしたかどうかで返す値が変わります。 具体的には、ContainsKeyメソッド・TryGetValueメソッドは、正規表現にマッチした場合、かつ正規表現内に指定された名前・番号のグループを含む場合のみtrue
を返します。 つまり、特定の名前・番号のグループにマッチしたかどうか表す値を返すのではないため、逆にいえばこのメソッドの戻り値から正規表現全体がマッチしたかどうかを知ることができます。
GroupCollection.TryGetValueメソッドを使って正規表現にマッチした場合にグループ化した箇所を取得する
Imports System
Imports System.Collections.Generic
Imports System.Text.RegularExpressions
Class Sample
Shared Sub Main()
' 整数表現にマッチする正規表現
' (符号部分を名前'sign'としてグループ化、絶対値部分を名前'number'としてグループ化)
Dim pattern As String = "(?<sign>\-|\+)?(?<number>[0-9]+)"
For Each text As String In New String() {"+123", "45", "abc"}
Dim m As Match = Regex.Match(text, pattern)
Console.Write($"{text} => {If(m.Success, "match", "not match")} ")
' 正規表現にマッチした場合は、グループ'sign'の部分を表示する
Dim sign As Group = Nothing
If m.Groups.TryGetValue("sign", sign) Then
Console.Write($"sign='{sign.Value}' ")
End If
' 正規表現にマッチした場合は、グループ'number'の部分を表示する
Dim number As Group = Nothing
If m.Groups.TryGetValue("number", number) Then
Console.Write($"number='{number.Value}' ")
End If
Console.WriteLine()
Next
End Sub
End Class
実行結果
+123 => match sign='+' number='123' 45 => match sign='' number='45' abc => not match