【问题标题】:Regular Expression to match process arguments正则表达式匹配进程参数
【发布时间】:2013-11-30 17:02:31
【问题描述】:

我有这个字符串:

Process.exe /Switch=Value /Switch="C:\Path with spaces\file.txt" wrong argument

我想捕捉这些部分:

· 1st Match: Process.exe
· 2nd Match: /Switch=Value
· 3rd Match: /Switch="C:\Path with spaces\file.txt"
· 4th Match: wrong
· 5th Match: argument

正则表达式需要用于一般用途(带有真实参数的过程),不仅适用于这种情况。

这是我正在尝试的:

Dim DebugArguments As String =
    "HotkeyMaker.exe /Hotkey=Escape /run=""c:\folder with spaces\notepad.exe"""

For Each match As Match In Regex.Matches(DebugArguments, "([^\s]+[^""])")
    MsgBox(match.Value)
Next match

【问题讨论】:

  • 在参数的布局规则中断之前,您无法解析它。有什么你能想到的吗?
  • 是否总是有 5 个且只有 5 个参数?
  • @ridgerunner 不,这只是一个例子,参数的数量是未定义的
  • @sin,对不起,我的英文不太好,什么意思?,语法类似于一些微软应用程序,例如 SC.exe 命令:sc.exe config themes type="own",但也带有@ 987654325@ 字符。

标签: c# .net regex vb.net


【解决方案1】:

编辑
在这里,一个用于解析 C/C++ 命令行参数的正则表达式。每个参数都需要
进一步子处理以解决参数级别的转义和双引号。

此外,这不会解析命令解释器 (cmd.exe) 首次解析的特殊管道/重定向符号。相反,这会分离(解析)传递给语言的 CreateProcess() 的字符串。这是 C/C++ 并且可能会被不同地解析,这取决于命令调用的语言

使用的参考 - http://www.daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULESREPH

Edit2添加了命令解析部分

 # CmdLineParser_Cpp.rxf
 # -------------------------------------------------------------------------------
 # Reference used - "How Command Line Parameters Are Parsed" C/C++ cmdline parsing:
 # http://www.daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULESREPH
 # -------------------------------------------------------------------------------

 #  (?:^[ \t]*((?>[^ \t"\r\n]+|"[^"]+(?:"|$))+)|(?!^)[ \t]+((?>[^ \t"\\\r\n]+|(?<!\\)(?:\\\\)*"[^"\\\r\n]*(?:\\.[^"\\\r\n]*)*"{1,2}|(?:\\(?:\\\\)*")+|\\+(?!"))+)|([^ \t\r\n]))
 #  "(?:^[ \\t]*((?>[^ \\t\"\\r\\n]+|\"[^\"]+(?:\"|$))+)|(?!^)[ \\t]+((?>[^ \\t\"\\\\\\r\\n]+|(?<!\\\\)(?:\\\\\\\\)*\"[^\"\\\\\\r\\n]*(?:\\\\.[^\"\\\\\\r\\n]*)*\"{1,2}|(?:\\\\(?:\\\\\\\\)*\")+|\\\\+(?!\"))+)|([^ \\t\\r\\n]))"
 #  @"(?:^[ \t]*((?>[^ \t""\r\n]+|""[^""]+(?:""|$))+)|(?!^)[ \t]+((?>[^ \t""\\\r\n]+|(?<!\\)(?:\\\\)*""[^""\\\r\n]*(?:\\.[^""\\\r\n]*)*""{1,2}|(?:\\(?:\\\\)*"")+|\\+(?!""))+)|([^ \t\r\n]))"

 (?:
      ^ [ \t]* 
      (                             # (1 start), Command
           (?>
                [^ \t"\r\n]+          
             |  
                " [^"]+ 
                (?: " | $ )
           )+
      )                             # (1 end)
   |  
      (?! ^ )
      [ \t]+                        # Delimeter
      (                             # (2 start), Argument
           (?>
                [^ \t"\\\r\n]+ 
             |  
                (?<! \\ )
                (?: \\ \\ )*
                " [^"\\\r\n]* (?: \\ . [^"\\\r\n]* )*  "{1,2}
             |  
                (?:
                     \\ (?: \\ \\ )*  " 
                )+
             |  
                \\+ (?! " )
           )+
      )                             # (2 end)
   |  
      ( [^ \t\r\n] )                # (3), Bad character
 )


 #   #use strict;
 #   #use warnings;
 #   
 #   my $string;
 #   
 #   while ($string = <DATA>)
 #   {
 #       chomp($string);
 #       next if (length($string) == 0);
 #   
 #       print "\nString To Parse:  '$string'\n";
 #   
 #       while ( $string =~ 
 #          m~(?:^[ \t]*((?>[^ \t"\r\n]+|"[^"]+(?:"|$))+)|(?!^)[ \t]+((?>[^ \t"\\\r\n]+|(?<!\\)(?:\\\\)*"[^"\\\r\n]*(?:\\.[^"\\\r\n]*)*"{1,2}|(?:\\(?:\\\\)*")+|\\+(?!"))+)|([^ \t\r\n]))~xg
 #             )
 #       {
 #          print "command:          $1\n" if (defined $1);   
 #          print "argument:         $2\n" if (defined $2);   
 #          print "bad char:         $3\n" if (defined $3);   
 #       }
 #   }
 #   __DATA__
 #   F:\"Program Files"\Test\"H "A\runthis.exe -arg
 #   "Console Application Template.vshost.exe" /Switch1=Value1 /Switch2="Value2"
 # 
 #   run-A  /Switch=Value /Switch="C:\Path with spaces\file.txt" -arg
 #   run-B  Hotkey="Escape"
 #   run-C  Command="Dir /B "*.*"" Path=..\..\
 #   
 #   run-01 CallMeIshmael
 #   run-02 "Call Me Ishmael"
 #   run-03 Cal"l Me I"shmael
 #   run-04 CallMe\"Ishmael 
 #   run-05 "CallMe\"Ishmael"
 #   run-06 "Call Me Ishmael\\" 
 #   run-07 "CallMe\\\"Ishmael" 
 #   run-08 a\\\b
 #   run-09 "\"Call Me Ishmael\"" 
 #   run-10 "C:\TEST A\\" 
 #   run-11 "\"C:\TEST A\\\""
 #   run-12 "a b c"  d  e
 #   run-13 "ab\"c"  "\\"  d
 #   run-14 a\\\b d"e f"g h
 #   run-15 a\\\"b c d
 #   run-16 a\\\\"b c" d e
 #   run-17 "a b c""
 #   run-18 """CallMeIshmael"""  b  c
 #   run-19 """Call Me Ishmael"""
 #   run-20 """"Call Me Ishmael"" b c
 #   run-21 """CallMeIshmael"""
 #   run-22 """Call Me Ishmael"""
 #   run-23 \"CallMeIshmael\"
 #   run-24 """"Call me Ishmael""""
 #   run-25 """"Call Me Ishmael""
 #   run-26 "\"Call Me Ishmael\""

输出>>

 String To Parse:  ' F:\"Program Files"\Test\"H "A\runthis.exe -arg'
 command:          F:\"Program Files"\Test\"H "A\runthis.exe
 argument:         -arg

 String To Parse:  ' "Console Application Template.vshost.exe" /Switch1=Value1 /S
 witch2="Value2"'
 command:          "Console Application Template.vshost.exe"
 argument:         /Switch1=Value1
 argument:         /Switch2="Value2"

 String To Parse:  ' run-A  /Switch=Value /Switch="C:\Path with spaces\file.txt"
 -arg'
 command:          run-A
 argument:         /Switch=Value
 argument:         /Switch="C:\Path with spaces\file.txt"
 argument:         -arg

 String To Parse:  ' run-B  Hotkey="Escape"'
 command:          run-B
 argument:         Hotkey="Escape"

 String To Parse:  ' run-C  Command="Dir /B "*.*"" Path=..\..\'
 command:          run-C
 argument:         Command="Dir /B "*.*""
 argument:         Path=..\..\

 String To Parse:  ' '

 String To Parse:  ' run-01 CallMeIshmael'
 command:          run-01
 argument:         CallMeIshmael

 String To Parse:  ' run-02 "Call Me Ishmael"'
 command:          run-02
 argument:         "Call Me Ishmael"

 String To Parse:  ' run-03 Cal"l Me I"shmael'
 command:          run-03
 argument:         Cal"l Me I"shmael

 String To Parse:  ' run-04 CallMe\"Ishmael '
 command:          run-04
 argument:         CallMe\"Ishmael

 String To Parse:  ' run-05 "CallMe\"Ishmael"'
 command:          run-05
 argument:         "CallMe\"Ishmael"

 String To Parse:  ' run-06 "Call Me Ishmael\\" '
 command:          run-06
 argument:         "Call Me Ishmael\\"

 String To Parse:  ' run-07 "CallMe\\\"Ishmael" '
 command:          run-07
 argument:         "CallMe\\\"Ishmael"

 String To Parse:  ' run-08 a\\\b'
 command:          run-08
 argument:         a\\\b

 String To Parse:  ' run-09 "\"Call Me Ishmael\"" '
 command:          run-09
 argument:         "\"Call Me Ishmael\""

 String To Parse:  ' run-10 "C:\TEST A\\" '
 command:          run-10
 argument:         "C:\TEST A\\"

 String To Parse:  ' run-11 "\"C:\TEST A\\\""'
 command:          run-11
 argument:         "\"C:\TEST A\\\""

 String To Parse:  ' run-12 "a b c"  d  e'
 command:          run-12
 argument:         "a b c"
 argument:         d
 argument:         e

 String To Parse:  ' run-13 "ab\"c"  "\\"  d'
 command:          run-13
 argument:         "ab\"c"
 argument:         "\\"
 argument:         d

 String To Parse:  ' run-14 a\\\b d"e f"g h'
 command:          run-14
 argument:         a\\\b
 argument:         d"e f"g
 argument:         h

 String To Parse:  ' run-15 a\\\"b c d'
 command:          run-15
 argument:         a\\\"b
 argument:         c
 argument:         d

 String To Parse:  ' run-16 a\\\\"b c" d e'
 command:          run-16
 argument:         a\\\\"b c"
 argument:         d
 argument:         e

 String To Parse:  ' run-17 "a b c""'
 command:          run-17
 argument:         "a b c""

 String To Parse:  ' run-18 """CallMeIshmael"""  b  c'
 command:          run-18
 argument:         """CallMeIshmael"""
 argument:         b
 argument:         c

 String To Parse:  ' run-19 """Call Me Ishmael"""'
 command:          run-19
 argument:         """Call
 argument:         Me
 argument:         Ishmael"""

 String To Parse:  ' run-20 """"Call Me Ishmael"" b c'
 command:          run-20
 argument:         """"Call Me Ishmael""
 argument:         b
 argument:         c

 String To Parse:  ' run-21 """CallMeIshmael"""'
 command:          run-21
 argument:         """CallMeIshmael"""

 String To Parse:  ' run-22 """Call Me Ishmael"""'
 command:          run-22
 argument:         """Call
 argument:         Me
 argument:         Ishmael"""

 String To Parse:  ' run-23 \"CallMeIshmael\"'
 command:          run-23
 argument:         \"CallMeIshmael\"

 String To Parse:  ' run-24 """"Call me Ishmael""""'
 command:          run-24
 argument:         """"Call me Ishmael""""

 String To Parse:  ' run-25 """"Call Me Ishmael""'
 command:          run-25
 argument:         """"Call Me Ishmael""

 String To Parse:  ' run-26 "\"Call Me Ishmael\""'
 command:          run-26
 argument:         "\"Call Me Ishmael\""

【讨论】:

  • 谢谢,这是一个标记为已接受的答案,但是表达真的很长时间才能理解你所做的一切,以确保我正在使用你的正则表达式,请你在您的答案中添加正则表达式可能产生的可能误报列表以及安全字符串列表?以理解我为例,这个论点:Hotkey="Escape"(注意 / 字符未写入)将返回 5 个匹配项。
  • @ElektroStudios - 我重新发布了大多数 MS 命令行参数的修复程序(尽管不是全部)。包括参数选项[[-/]val[=["dat"][dat][]]] 或独立的["val"]
  • 现在完美了,似乎是一个通用的正则表达式,以前的正则表达式只适用于这种参数:“/Switch=value”,感谢您的时间,如果您可以改进,请随时更新更多!
  • 抱歉,修复了剪切粘贴错误。这现在有效。最好使用最后一次更新。
  • 您能否修复正则表达式以在引号内使用引号?例如在这个论点中:-Command="Dir /B "*.*""
【解决方案2】:

试试这样的。

 Dim DebugArguments As String =
    "HotkeyMaker.exe /Hotkey=""Escape"" /run=""c:\folder with spaces\notepad.exe"""
 Dim myMatches As MatchCollection
 Dim MyRegEx As New Regex("([^\/]+""|[^/\s]+)")

 myMatches = MyRegEx.Matches(DebugArguments)

 For Each match In myMatches
 MsgBox(match.Value)
 Next

【讨论】:

  • 不起作用,您使用了与我在问题中使用的相同(错误)模式。该模式得到的是这样的:/run="c:\folder,但预期是这样的:/run="c:\folder with spaces\notepad.exe"
  • 我做了一点修改:([^\/]+[^\s\/]) 编辑:但仍然不能使用这个例子:"HotkeyMaker.exe /Hotkey=Escape /run=""c:\folder with spaces\notepad.exe"" wrong argument"
  • 尽管如此,匹配 2 和 3 中缺少 /。
  • 我将代码更改为新的正则表达式,试一试。为我工作!
猜你喜欢
  • 1970-01-01
  • 2017-12-01
  • 2016-09-12
  • 1970-01-01
  • 2011-10-21
  • 1970-01-01
  • 1970-01-01
  • 2019-03-30
  • 2011-05-01
相关资源
最近更新 更多