1

たとえば、他の 2 つの文字列の間にある文字列を返す小さな関数があります (一重引用符、二重引用符、または単純な html タグの間を考えてください)。

        Dim exp As String = String.Format("{0}(.*?){1}", beginMarker, endMarker)

ここで、beginMarker に "<b>" を渡し、終了マーカーに "</b>" を渡し、RegEx.Ignore case を指定しないと、一致する小文字 <b></b に対して正しく返されます。 >。ただし、IgnoreCase を指定すると、返されることはありません (同じ入力を想定)。関数の例を次に示します (RegexOptions.IgnoreCase を削除すると機能します)。また、入力されているマーカーをエスケープしても、出力は変わらないようです。唯一の違いは IgnoreCase です。

私の質問は、何が欠けているのですか (実際には HTML を属性で解析していないため、簡単な例を使用しました)?

入力: beginMarker = "<b>"
入力: endMarker = "</b>"
入力: searchText = "<b>これはテストです</b>"
入力: beginMakers (True または False は関係ありません)

Public Shared Function GetStringInBetween(beginMarker As String, endMarker As String, searchText As String, includeMarkers As Boolean) As List(Of String)
    beginMarker = RegularExpressions.Regex.Escape(beginMarker)
    endMarker = RegularExpressions.Regex.Escape(endMarker)
    Dim exp As String = String.Format("{0}(.*?){1}", beginMarker, endMarker)
    Dim regEx As New RegularExpressions.Regex(exp)
    Dim returnList As New List(Of String)

    For Each m As Match In regEx.Matches(searchText, 0, RegexOptions.IgnoreCase)
        If includeMarkers = True Then
            returnList.Add(m.Value)
        Else
            returnList.Add(m.Value.TrimStart(beginMarker.ToCharArray).TrimEnd(endMarker.ToCharArray))
        End If
    Next

    Return returnList
End Function
4

1 に答える 1

3

混乱を招く可能性があるため、変数の名前に .NET クラス名は使用しません。

これは機能し、Trim 関数を変更して大文字と小文字を区別しないようにしました。

Imports System.Text.RegularExpressions

Module Module1

    Public Function GetStringInBetween(beginMarker As String, endMarker As String, searchText As String, includeMarkers As Boolean) As List(Of String)
        Dim exp As String = String.Format("{0}(.*?){1}", Regex.Escape(beginMarker), Regex.Escape(endMarker))
        Dim returnList As New List(Of String)

        For Each m As Match In Regex.Matches(searchText, exp, RegexOptions.IgnoreCase)
            If includeMarkers Then
                returnList.Add(m.Value)
            Else
                ' return the portion of the matched string without the markers
                returnList.Add(m.Value.Substring(beginMarker.Length, m.Value.Length - beginMarker.Length - endMarker.Length))
            End If
        Next

        Return returnList

    End Function

    Sub Main()
        ' include a \ to confirm the regex escaping 
        ' outputs: "hello, again"
        Console.WriteLine(String.Join(", ", GetStringInBetween("<x>", "</\x>", "<X>hello</\x> world <x>again</\x>", False).ToArray))
        Console.ReadLine()
    End Sub

End Module

編集:そうそう、Option Strict Onも使用してください。また、(String, Int32, String) をパラメーターとして受け取る RegEx.Matches のオーバーロードはありません。

于 2012-07-23T18:15:17.287 に答える