سؤال

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:

  1. The command line may or may not lead off with the pathname.
  2. If the pathname is present, it will be quoted.
  3. The pathname will be an absolute path. As such, it will contain Regex special characters such as "\", ".", and possibly others.
  4. 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.
  5. The pathname may also appear among the arguments. If so, such occurrences should be preserved and returned with the rest of the arguments.
  6. Whitespace characters surrounding the leading pathname should be discarded.
  7. 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!

هل كانت مفيدة؟

المحلول

See Regex.Escape. I think that's the only thing you're missing. Used like

string pattern = 
    @"^\s*(?:""" + Regex.Escape(pathname) + """)?\s*(.*)";

نصائح أخرى

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:

enter image description here

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top