我需要一个正则表达式来解析命令,例如:
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
复制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 :(得分:1)
如果您使用的是标准的控制台应用程序,那么主入口点args []已经为您解析了这个问题。这里有一个警告,因为你提供的例子因为它们中的空格(C:\ Program Files)而无法工作,但如果你用引号括起它们(“C:\ Program Files \ Internet ... \ iexplorer”) .exe“)你会发现这个工作正常。
这link walks you through creating a console application
<强>更新强>
那么,如果它不是控制台应用程序,但您想要模拟控制台应用程序启动例程为您提供的确切内容,我可以向您介绍唯一的 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);
}
}
}
答案 1 :(得分:1)
根据您的问题,我假设您正在寻找一种在Windows操作系统上以文本形式传递批处理命令的方法。我能想到你成功做到这一点的唯一方法是,如果你有一个所有命令的列表,或者如果你的程序可以提取系统中的所有.exe文件,那么你可以成功检查第一个exe文件的位置< em>这是命令的目标程序,并将其他程序视为参数。
这样,你可以像这样进行提取(非正则表达式方法):
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
}
}
}
答案 2 :(得分:0)
你需要在程序路径/名称周围加上引号(如果它有空格),或者写一些额外的代码来找出它的程序部分。
首先想到的一种方法是从第一次捕获开始(对于iexplorer.exe
示例,它将是C:\Program
),检查它是否是有效的程序。如果没有,请使用空格添加下一个捕获(例如,C:\Program
+ Files\Internet
=&gt; C:\Program Files\Internet
)并重复检查。重复,直到你用完捕获或找到一个有效的程序,并将其余部分视为正常参数。
没有理由手动进行解析,正如另一个答案所示。正则表达式仍然有效。