Vb.net 按空格拆分shell命令,但允许使用引号将多个单词参数括起来
我想编写一个像命令shell一样工作的应用程序(请求一个命令,执行它,然后请求下一个命令,重复)。然而,当我试图将书面命令拆分为单独的部分时,我立即失败了 我不仅要在空格处拆分命令,而且要允许参数包含空格,只要将它们放在双引号之间 我无法找出我的代码出了什么问题,即使我逐行检查它Vb.net 按空格拆分shell命令,但允许使用引号将多个单词参数括起来,vb.net,Vb.net,我想编写一个像命令shell一样工作的应用程序(请求一个命令,执行它,然后请求下一个命令,重复)。然而,当我试图将书面命令拆分为单独的部分时,我立即失败了 我不仅要在空格处拆分命令,而且要允许参数包含空格,只要将它们放在双引号之间 我无法找出我的代码出了什么问题,即使我逐行检查它 Module Module1 Dim _exit As Boolean = False Dim prompt As String = "" Dim Title As String = ""
Module Module1
Dim _exit As Boolean = False
Dim prompt As String = ""
Dim Title As String = ""
Sub Main()
Console.Title = Title
While Not _exit
Console.Write(prompt)
Dim returned As String = Console.ReadLine
Dim parts() As String = split_with_string(returned, False)
If parts(0) = "exit" Then
_exit = True
ElseIf parts(0) = "" Then
'Space for Commands
Else
Console.WriteLine("Unknown Command")
End If
End While
End Sub
Private Function secindex(ByVal str As String, character As Char)
Return str.IndexOf(character, str.IndexOf(character) + 1)
End Function
Private Function split_with_string(ByVal str As String, ByVal return_parts As Boolean)
Dim returned As String = str
Dim parts As New List(Of String)
_next:
If returned.Length = 1 Then
parts.Add(returned)
ElseIf returned.StartsWith("""") Then
parts.Add(returned.Substring(1, secindex(returned, """") - 1))
returned = returned.Substring(secindex(returned, """") + 1)
ElseIf returned.StartsWith(" ") Then
returned = returned.Substring(1)
Else
If returned.Contains(" ") Then
parts.Add(returned.Substring(0, returned.IndexOf(" ")))
returned = returned.Substring(returned.IndexOf(" ") + 1)
Else
parts.Add(returned)
returned = ""
End If
End If
If Not returned.Length < 1 Then
GoTo _next
End If
If return_parts Then
For Each xx In parts.ToArray
Console.WriteLine(xx)
Next
End If
Return parts.ToArray
End Function
End Module
模块1
Dim _以布尔值形式退出=False
Dim提示符为String=“”
Dim Title As String=“”
副标题()
Console.Title=Title
而不是退出
Console.Write(提示符)
Dim返回为String=Console.ReadLine
Dim parts()作为字符串=使用字符串分割(返回,False)
如果零件(0)=“退出”,则
_退出=真
其他部分(0)=“然后
'命令空间
其他的
Console.WriteLine(“未知命令”)
如果结束
结束时
端接头
私有函数secindex(ByVal str作为字符串,字符作为字符)
返回str.IndexOf(字符,str.IndexOf(字符)+1)
端函数
带字符串的私有函数拆分(ByVal str作为字符串,ByVal return作为布尔值)
Dim返回为String=str
将零件标注为新列表(字符串)
_下一步:
如果返回.Length=1,则
零件。添加(已返回)
ElseIf返回。然后用(“”)开始
parts.Add(返回的.Substring(1,secindex(返回的“”)-1))
returned=returned.Substring(secindex(returned,“”“”)+1)
ElseIf返回。然后用(“”)开始
returned=returned.Substring(1)
其他的
如果返回。包含(“”),则
parts.Add(返回的.Substring(0,返回的.IndexOf(“”))
returned=returned.Substring(returned.IndexOf(“”+1)
其他的
零件。添加(已返回)
returned=“”
如果结束
如果结束
如果未返回,则长度<1
下一个
如果结束
如果返回零件,则
对于每个xx部件,请参见图1
控制台写入线(xx)
下一个
如果结束
将零件返回到阵列
端函数
端模块
如果布尔值设置为true,我希望函数将结果写入控制台。Regex使复杂字符串解析变得如此简单。它本身有一个陡峭的学习曲线,但由于它是许多语言和编程工具中可用的标准工具,您迟早应该熟悉它 例如,如果要获得如下所示的列表:
1
二
“这是三个”
“这是四个”
五
您可以使用如下代码:
Public Sub-Main()
Dim parts()作为String=ParseCommand(“一两”这是三“”这是四”“五”)
对于每个零件,将其作为零件中的字符串
控制台写入线(部分)
下一个
端接头
私有函数ParseCommand(作为字符串输入)作为字符串()
返回Regex.Matches(输入“(?!”)\S+|“[^”“]+”)。
(比赛的)演员。
选择(功能(m)m.Value)。
ToArray()
端函数
但是,如果希望删除引号,则输出如下所示:
1
二
这是三个
这是四
五
您可以对正则表达式模式进行一些调整,如下所示:
Private Function ParseCommand(作为字符串输入)作为字符串()
返回Regex.Matches(输入“(?(?!”)\S+)|“(?[^”“]+)”)。
(比赛的)演员。
选择(功能(m)m.组(“p”).值)。
ToArray()
端函数
如果您不熟悉正则表达式,它将使用一种模式来查找输入字符串中匹配的子字符串。在第一个示例中,它所寻找的模式是(?!”)\s+|“[^”]+”
。因此,它在输入字符串中查找与该模式匹配的所有部分,并只返回那些匹配的子字符串。以下是该模式的含义:
-匹配任何不以(?!”)\S+
开头的单词“
-包含在(?!”
子句中的任何内容都被称为消极前瞻。这意味着无论接下来发生什么,都不能是该子句中列出的内容。在这种情况下,这意味着接下来发生的任何内容都不能以(?!…)
字符开头“
-这是指任何非空格字符,因此任何不是空格、制表符或类似字符的字符\S
-这意味着必须有一个或多个非空格字符+
-这意味着布尔或,意味着它可以匹配它前面的任何内容或它后面的任何内容|
-这匹配两个“[^”]+”
字符之间的所有单词,包括任何空格“
-表示匹配必须以“
开头”
-包含在[^”]
子句中的任何字符都是负数字符类。这意味着它可以是不是子句中列出的字符之一的任何字符。在这种情况下,它表示任何非[^…]
的字符“
-这意味着必须有一个或多个非引号字符+
-表示匹配必须以“
”
(?子模式)
)来匹配整个匹配的某些部分