我有一个字符串(它会改变它的每次出现),如下所示:
<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
中?
答案 0 :(得分: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>.*?)
,它不仅指示它匹配任何子字符-string,但也将名称key
分配给通配符。为其指定名称意味着我们可以在代码中轻松引用它以获取其值。
示例代码使用该模式创建正则表达式对象,然后通过调用keyString
在regEx.Matches(keyString)
变量上运行搜索。该方法返回Match
个对象的集合,这些对象表示keyString
中模式的每个匹配项。然后,它会调用m.Groups("key").Value
以获取每个匹配项中key
组(通配符部分)的值。
答案 1 :(得分: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
答案 2 :(得分: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
答案 3 :(得分: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