1

C#を使用して.NET4.0で開発する。(これが長蛇の列である場合は申し訳ありません...)

次のようなメソッドを作成したい:

public static string GetCmdLineArgs(
    string cmdLine,
    string pathname )
{
    ...
}

実行可能ファイルのパス名のに引数を抽出できる正規表現パターンを作成したいと思います。ルール:

  1. コマンドラインは、パス名で始まる場合とそうでない場合があります。
  2. パス名が存在する場合は、引用符で囲まれます。
  3. パス名は絶対パスになります。そのため、「\」、「。」などの正規表現の特殊文字が含まれる可能性があります。
  4. 引用符で囲まれたパス名がコマンドラインの先頭に表示されない場合は、コマンドラインをキャプチャして返すだけで、先頭の空白を差し引いてください。
  5. パス名も引数の中に表示される場合があります。その場合、そのようなオカレンスは保持され、残りの引数とともに返される必要があります。
  6. 先頭のパス名を囲む空白文字は破棄する必要があります。
  7. 今のところ、すべての引数を1つの文字列で返すだけで十分ですが、将来、特定の引数のキャプチャグループが追加される可能性があります。

簡単な操作でこの関数を一緒にハックできることはSystem.Stringわかっていますが、将来の変更に備えて柔軟性を維持するために、正規表現マッチングを使用してこの関数を実行する方法も知りたいです。

基本的に、私は次のようなことをしたいと思います。

// 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...
}

明らかに、にRegex特殊文字が含まれているため、上記はそのままでは機能しませんpathname。私が説明したように機能するようにこれを変更する方法はありますか?エスケープされていない文字列に一致させるグループ化演算子はありますか、それともpathnameすべての可能な特殊文字をエスケープして変換する必要がありますか?

これが他の場所で質問され、回答された場合は、その投稿を教えてください。ありがとう!

4

2 に答える 2

3

を参照してくださいRegex.Escape。私はそれがあなたが見逃している唯一のものだと思います。のように使用

string pattern = 
    @"^\s*(?:""" + Regex.Escape(pathname) + """)?\s*(.*)";
于 2012-10-08T17:37:11.360 に答える
0

ハード値ではなく、アンカータイプのトークンで機能します。この例では、-がコマンドラインオプションを "を持つパスから分割することを知っています。これにより、出力をトークン化し、引数の順序と含むパスを抽出できます。If条件付き(? )正規表現で、パスアイテムからコマンドライン引数を除外します。

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
                  })
                  ;

トークンの出力は次のとおりです。

ここに画像の説明を入力してください

于 2012-10-08T17:42:34.120 に答える