2

我设法在 2 个指定字符串之间找到了一个字符串,现在唯一的问题是它只会找到一个然后停止。

我怎样才能让它抓住文本框中的所有字符串?文本框是多行的,我在里面放了一个小配置。

现在我希望列表框将添加我的 2 个指定字符串之间的所有字符串。

textbox3.text 包含“<”和 textbox 4.text 包含“>”

Public Function GetClosedText(ByVal source As String, ByVal opener As String, ByVal closer As String) As String
    Dim intStart As Integer = InStr(source, opener)
    If intStart > 0 Then
        Dim intStop As Integer = InStr(intStart + Len(opener), source, closer)
        If intStop > 0 Then
            Try
                Dim value As String = source.Substring(intStart + Len(opener) - 1, intStop - intStart - Len(opener))
                Return value
            Catch ex As Exception
                Return ""
            End Try
        End If
    End If
    Return ""
End Function


usage:
ListBox1.Items.Add(GetClosedText(TextBox1.Text, TextBox3.Text, TextBox4.Text))
4

2 回答 2

3

最简单的方法(最少的代码行)是使用正则表达式。例如,要查找包含在尖括号中的所有字符串,您可以使用以下正则表达式:

\<(?<value>.*?)\>

这就是这一切的含义:

  • \<- 查找以字符开头的字符串<。由于<在RegEx中有特殊含义,所以必须转义(即前面加反斜杠)
  • (?<value>xxx)- 这将创建一个命名组,以便我们稍后可以通过名称访问匹配字符串的这一部分"value"。名称组中包含的所有内容(即 where xxxis)都被视为该组的一部分。
  • .*?- 这意味着找到任意数量的任意字符,最多但不包括接下来的任何字符。The.是一个通配符,表示任何字符。*表示任意次数。这?使它变得非贪婪,因此一旦找到接下来发生的任何事情(关闭>),它就会停止匹配。
  • \>- 指定匹配的字符串必须以>字符结尾。由于>在 RegEx 中具有特殊含义,因此也必须进行转义。

您可以使用该 RegEx 表达式来查找所有匹配项,如下所示:

Dim items As New List(Of String)()
For Each i As Match In Regex.Matches(source, "\<(?<value>.*?)\>")
    items.Add(i.Groups("value").Value)
Next

使它在您的场景中工作的技巧是您需要动态指定开始和结束字符。您可以通过将它们连接到 RegEx 来做到这一点,如下所示:

Regex.Matches(source, opener & "(?<value>.*?)" & closer)

但问题是,这只有在source并且closer不是特殊的 RegEx 字符时才有效。在您的示例中,它们是<and >,它们是特殊字符,因此需要对其进行转义。做到这一点的安全方法是使用该Regex.Escape方法,该方法仅在需要时转义字符串:

Private Function GetClosedText(source As String, opener As String, closer As String) As String()
    Dim items As New List(Of String)()
    For Each i As Match In Regex.Matches(source, Regex.Escape(opener) & "(?<value>.*?)" & Regex.Escape(closer))
        items.Add(i.Groups("value").Value)
    Next
    Return items.ToArray()
End Function

请注意,在上面的示例中,我没有找到单个项目并返回它,而是将GetClosedText函数更改为返回一个字符串数组。所以现在,你可以这样称呼它:

ListBox1.Items.AddRange(GetClosedText(TextBox1.Text, TextBox3.Text, TextBox4.Text))
于 2013-09-27T12:47:57.467 回答
1

我假设您想循环所有开启者和关闭者:

' always use meaningful variable/control names instead of
If TextBox3.Lines.Length <> TextBox4.Lines.Length Then 
    MessageBox.Show("Please provide the same count of openers and closers!")
    Return
End If

Dim longText = TextBox1.Text
For i As Int32 = 0 To TextBox3.Lines.Length - 1
    Dim opener = TextBox3.Lines(i)
    Dim closer = TextBox4.Lines(i)
    listBox1.Items.Add(GetClosedText(longText, opener , closer))
Next

但是,您应该使用 .NET 方法,如下所示

Public Function GetClosedText(ByVal source As String, ByVal opener As String, ByVal closer As String) As String
    Dim indexOfOpener = source.IndexOf(opener)
    Dim result As String = ""
    If indexOfOpener >= 0 Then ' default is -1 and indices start with 0
        indexOfOpener += opener.Length ' now look behind the opener
        Dim indexOfCloser = source.IndexOf(closer, indexOfOpener)
        If indexOfCloser >= 0 Then
            result = source.Substring(indexOfOpener, indexOfCloser - indexOfOpener)
        Else
            result = source.Substring(indexOfOpener) ' takes the rest behind the opener
        End If
    End If
    Return result
End Function
于 2013-09-27T12:13:22.627 回答