1

我有一个字符串(每次出现都会改变),看起来像这样: <Left Mouse Up> <Right Mouse Up> <Press V><Press Up><Press Q><Press Up><Press L>我需要读取单词后面的每个字母实例Press并将它们存储在一个列表中,但我不太确定该怎么做。我现在有这段代码可以读取整个字符串,以及单词后面的每个字母实例,Press但它不会立即将它们存储在列表中,而是在迭代之后存储。

Dim keyString = command.ToString
    Dim allKeys As New List(Of String)
    Dim pattern = "Press "
    Dim index = keyString.IndexOf(pattern)
    While index >= 0
        index += pattern.Length
        Dim endIndex = keyString.IndexOf(">", index)
        If endIndex >= 0 Then
            Dim nextKey = keyString.Substring(index, endIndex - index)
            allKeys.Add(nextKey)
            index = keyString.IndexOf(pattern, endIndex + 1)

所以我想,简而言之,我将如何使它扫描整个字符串并将字符的每个实例存储Press到列表中allKeys

4

4 回答 4

3

您可以使用正则表达式 (RegEx) 更轻松地完成此任务。如果您还没有接触过正则表达式,它们可能有点令人生畏,但正如您所见,花时间学习这项技术是值得的。正则表达式非常强大,非常适合这类问题。

Dim keyString As String = "<Left Mouse Up> <Right Mouse Up> <Press V><Press Up><Press Q><Press Up><Press L>"
Dim regEx As New Regex("<Press (?<key>.*?)>")
Dim allKeys As New List(Of String)()
For Each m As Match In regEx.Matches(keyString)
    allKeys.Add(m.Groups("key").Value)
Next

我在示例中使用的正则表达式是<Press (?<key>.*?)>. 表达式的部分意思是:

  • <Press- 匹配的字符串必须以这些字符开头。
  • (?<key>- 开始一组名为key.
  • .*- 匹配任意字符任意次数。
  • ?- 使表达式不贪婪。换句话说,任何字符的任意多次匹配只包括到第一个>字符,这将在后面指定。如果问号不存在,则该模式将是贪婪的,因此它将匹配整个字符串直到最后一个>字符。
  • )- 结束命名组。
  • >- 匹配的字符串必须以此字符结尾。

简单来说,正则表达式使用高级通配符定义搜索模式。如果我们*用作简单的通配符,它​​看起来像<Press *>. 换句话说,我们希望找到以 开头<Press、以 结尾>并且介于两者之间的子字符串的所有实例。然而,在 RegEx 模式中,通配符部分可以更强大,通配符不是一个简单的*字符,而是通配符(?<key>.*?)不仅指示它匹配任何子字符串,而且将名称分配key给通配符。给它命名意味着我们可以很容易地在代码中引用它来获取它的值。

示例代码使用该模式创建一个正则表达式对象,然后keyString通过调用regEx.Matches(keyString). 该方法返回一个对象集合,Match这些对象代表keyString. 然后,它调用m.Groups("key").Valuekey从每个匹配项中获取组的值(通配符部分)。

于 2013-07-09T12:48:08.067 回答
1

这是一个简单的子程序,它将解析您的字符串并使用您传递给它的列表添加到列表中,该列表应在添加每个项目时更新:

Private Sub FillList(ByRef PressList As List(Of String), PressString As String)
    For Each token As String In PressString.Split({"Press"}, StringSplitOptions.None)
        If Not token.StartsWith("<") Then PressList.Add(token.Split(">"c)(0))
    Next
End Sub
于 2013-07-09T17:33:11.623 回答
1

您可以使用正则表达式:

Dim allKeys As New List(Of String)
Dim s As String = "<Left Mouse Up> <Right Mouse Up> <Press V><Press Up><Press Q><Press Up>   <Press L>"

Dim regx As Regex = New Regex("<(Press) ([\w+\s*]+)(>)")
Dim mcollection As MatchCollection = regx.Matches(s)
For Each m As Match In mcollection
    allKeys.Add(m.Groups(2).Value)
Next
于 2013-07-09T12:38:44.817 回答
0

首先,我将使用 .Split 标记字符串并将其拆分为标签。如果您的标签之间有空格,您可能需要将其解析出来。尝试这样的事情:

Dim allKeys As New List(Of String)
Dim myString As String = "<Left Mouse Up> <Right Mouse Up> <Press V><Press Up><Press Q><Press Up><Press L>"
Dim tokens As IEnumerable(Of String) = myString.Replace("> <", "><").Split("><")
tokens = (From t In tokens Where t.Contains("<Press "))
For Each t In tokens
  allKeys.Add(t.Replace("<Press ", String.Empty).Replace(">", String.Empty))
Next t
于 2013-07-09T12:33:26.557 回答