How to use a Regex to search for a filename within a command line string?
-
05-07-2021 - |
Pregunta
Developing in .NET 4.0 using C#. (Sorry if this is long-winded...)
I want to create a method such as:
public static string GetCmdLineArgs(
string cmdLine,
string pathname )
{
...
}
I want to create a Regex pattern that will let let me extract the arguments after the pathname of the executable file. The rules:
- The command line may or may not lead off with the pathname.
- If the pathname is present, it will be quoted.
- The pathname will be an absolute path. As such, it will contain Regex special characters such as "\", ".", and possibly others.
- If the quoted pathname does not appear at the beginning of the command line, just capture and return the command line, less any leading whitespace.
- The pathname may also appear among the arguments. If so, such occurrences should be preserved and returned with the rest of the arguments.
- Whitespace characters surrounding the leading pathname should be discarded.
- For now, it is sufficient to return all of the arguments in a single string, but capture groups for specific arguments may be added in the future.
I realize that I could hack this function together by using simple System.String
operations, but I also want to know how to do it using Regex matching to preserve flexibility for future changes.
Basically, I want to do something like:
// Create the pattern:
// The pathname is anchored to the beginning of the pattern.
// The pathname group is non-capturing.
// Additional capture groups may be added in the future.
string pattern =
@"^\s*(?:""" + pathname + """)?\s*(.*)";
Regex regex = new Regex( pattern );
Match = regex.Match( cmdLine );
if ( match.Success )
{
// extract matching groups...
}
Obviously, the above won't work as-is because of the presence of Regex special characters in pathname
. Is there some way to modify this so it works as I've described? Is there a grouping operator that will let me match an unescaped string, or would I have to transform pathname
by escaping all possible special characters?
If this has been asked and answered elsewhere, please point me to that post. Thanks!
Solución
See Regex.Escape
. I think that's the only thing you're missing. Used like
string pattern =
@"^\s*(?:""" + Regex.Escape(pathname) + """)?\s*(.*)";
Otros consejos
Don't work with hard values but with anchor type tokens. In this example I know that the - divides the command line options from the path which has a ". That way I have tokenized the output and can extract the order of the arguments and the path which contains. I am using the If conditional (? ) in regex to filter out the command line arguments from the path item.
string commandLine = @"-abc -log ""C:\Test it"" -def";
// \x22 is the escape for "
string pattern = @"
(?(\x22) # If a " then capture
((?:\x22)(?<Path>[^\x22]+)(?:\x22))
| # Or
((?:-)(?<Command>[^-\s]+)(?:\s?)) # It is a - and capture
)
";
var tokens = Regex.Matches(commandLine, pattern, RegexOptions.IgnorePatternWhitespace)
.OfType<Match>()
.Select (m => new
{
Arg = m.Groups["Command"].Value,
Path = m.Groups["Path"].Value
})
;
Output of tokens is: