2012-11-04 80 views
2

我需要一个正则表达式解析如命令:定期解析命令行表达

C:\ Program Files文件\的Internet Explorer \ IEXPLORE.EXE HTTPS:\ www.google.com
C: \ Program Files \ Internet Explorer \ iexplore.exe http:\ www.google.com
C:\ Program Files \ Internet Explorer \ iexplore.exe www.google.com
iexplore.exe https:\ www.google.com
copy C:\ test.txt D:\

问题是,我想让第一部分作为命令,其他部分作为参数。命令可以是任何东西,包括.bat.vbs.exe

找到,其正常工作,如果在命令中没有空间正则表达式。

string str = @"C:\xcopy D:\test.txt D:\Test"; 

string pattern = @"^(?:""([^""]*)""\s*|([^""\s]+)\s*)+";   
Regex parseDir = new Regex(pattern, RegexOptions.IgnoreCase); 
if(parseDir.IsMatch(str)) 
{ 
    Match dir = parseDir.Match(str); 
    var captures = dir.Groups[1].Captures.Cast<Capture>().Concat(
     dir.Groups[2].Captures.Cast<Capture>()). 
     OrderBy(x => x.Index). 
     ToArray(); 
    string cmd = captures[0].Value; 
    string arguments = string.Empty; 
    for (int i = 1; i < captures.Length; i++) 
    { 
     arguments += captures[i].Value + " ";  
    } 
    Console.WriteLine(cmd); 
    Console.WriteLine(arguments); 
} 
+0

你试图解析的字符串中的命令(来自用户输入,文件等)还是它们在初始化应用程序时传递的字面命令行参数? – newfurniturey

+0

是的,它是我需要解析问题的一个字符串,它在命令中可以是一个空格,并且我不能通过空格拆分它。 – Aram

+0

您可以发布一个描述这种工作方式的输出示例吗? :) –

回答

1

如果您使用的是标准的控制台应用程序,主入口点args []已经为您解析过。这里有一个警告,因为你提供的例子不会工作,因为它们中的空格(C:\ Program Files),但是如果你用引号括住它们(“C:\ Program Files \ Internet ... \ iexplorer .exe“),你会发现这个工作正常。

link walks you through creating a console application

UPDATE:

那么,如果它不是一个控制台应用程序,但你想模仿正是控制台应用程序的启动程序为您提供,我可以介绍你的唯一CommandLineToArgvW原生方法。

[DllImport("shell32.dll", SetLastError = true)] 
    static extern IntPtr CommandLineToArgvW(
     [MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine, 
     out int pNumArgs); 

这个可笑的简单方法采用任何字符串并将其转换为数组。这里有一个实用程序类,您可以使用它将文本输入转换为格式良好的数组。

/// <summary> 
/// Wrapper class for Win32 API calls 
/// </summary> 
public class NativeMethods 
{ 

    [DllImport("shell32.dll", SetLastError = true)] 
    static extern IntPtr CommandLineToArgvW(
     [MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine, out int pNumArgs); 

    /// <summary> 
    /// Parse a string into an array, including items in quotes 
    /// </summary> 
    /// <param name="commandLine"></param> 
    /// <returns></returns> 
    public static string[] CommandLineToArgs(string commandLine) 
    { 
     if (String.IsNullOrEmpty(commandLine)) 
      return new string[] {}; 

     int argc; 
     var argv = CommandLineToArgvW(commandLine, out argc); 
     if (argv == IntPtr.Zero) 
      throw new System.ComponentModel.Win32Exception(); 
     try 
     { 
      var args = new string[argc]; 
      for (var i = 0; i < args.Length; i++) 
      { 
       var p = Marshal.ReadIntPtr(argv, i * IntPtr.Size); 
       args[i] = Marshal.PtrToStringUni(p); 
      } 

      return args; 
     } 
     finally 
     { 
      Marshal.FreeHGlobal(argv); 
     } 
    } 
} 
+0

感谢您的答复。不,它不是带有参数的控制台应用程序有文本框,我可以在其中粘贴命令和参数,我需要解析它以便分离命令和参数并发送它们以供执行。 – Aram

+0

其实我不想解析只是我想解析洞字符串的参数在哪里有参数的命令让我解释我有什么,我需要什么我开发了客户端服务器应用程序,其中服务器可以发送命令给多个客户端执行和命令只是一个字符串我需要解析的一点是,我只想分开命令我不在乎有多少参数,例如可以有C:\ test.exe arg0 arg1 ...或test.exe arg0 arg1 ..或者C:\ program files \ test.exe arg0 arg1 ...我在这种情况下需要解析并获取命令(test.exe或C:\ test.exe或...) – Aram

+0

Path.GetFileName (arg [0]) – bryanbcook

1

从你的问题,我假设你正在寻找一种方式来传递在Windows操作系统文本批处理命令。我能想到的唯一方法就是成功完成这个任务,如果你有一个所有命令的列表,或者你的程序能够提取系统中的所有.exe文件,那么你可以成功地检查第一个exe文件的位置这是命令的目标程序是并假设其他人作为参数。

这样一来,你可以做你的提取像这样的(非正则表达式的方法):

var cmd = "copy this.txt C:\t.txt" 
var program = getTargetProgram(cmd); 
var args = cmd.Substring(cmd.IndexOf(program) + program.length).trim().split(' '); 

getTargetProgram()可能是这样的:

private string getTargetProgram(string cmd) 
{ 
    //first test if it's a normal executable 
    if(File.Exists(cmd.Substring(0, cmd.IndexOf(".exe") + 4)) //return this extract; 
    foreach(string s in winProgramList) 
    { 
     if(cmd.StartsWith(s)){ 
      //voila, we can return the target 
     } 
    } 
} 
+0

在这种情况下,我需要有程序列表和程序类型,因为命令不会只是.exe文件 – Aram

+0

,您通常可以通过在命令提示符窗口中键入帮助或只是提取所有* .exe *从你的系统目录,即' Directory.GetFiles(@“C:\ Windows \ system32”,* .exe);' –

0

你要么需要把周围的报价程序路径/名称(如果它有空格),或者编写一些额外的代码来确定程序的一部分。

想到的一种方法是从第一次捕获开始(对于您的iexplorer.exe示例,它将是C:\Program),检查它是否是有效的程序。如果不是,请添加一个空格(例如,C:\Program + Files\Internet =>C:\Program Files\Internet)并重复检查。重复,直到你已经用完了捕捉或者找到了一个有效的程序,并将其余的部分作为参数正常处理。

没有理由手动进行解析,因为提出了另一个答案。正则表达式仍然有效。