0

C#で次のパターンの正規表現があります

Regex param = new Regex(@"^-|^/|=|:");

基本的に、コマンドライン解析用です。

以下のコマンドライン引数を渡すと、それも分割C:されます。

/Data:SomeData /File:"C:\Somelocation"

二重引用符または単一引用符内の文字に適用されないようにするにはどうすればよいですか?

4

2 に答える 2

2

これは、次の 2 つの手順で行うことができます。

最初の正規表現を使用する

Regex args = new Regex("[/-](?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");

文字列を異なる引数に分割します。次に、正規表現を使用します

Regex param = new Regex("[=:](?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");

各引数をパラメーター/値のペアに分割します。

説明:

[=:]      # Split on this regex...
(?=       # ...only if the following matches afterwards:
 (?:      # The following group...
  [^"]*"  #  any number of non-quote character, then one quote
  [^"]*"  #  repeat, to ensure even number of quotes
 )*       # ...repeated any number of times, including zero,
 [^"]*    # followed by any number of non-quotes
 $        # until the end of the string.
)         # End of lookahead.

基本的に、前方に偶数個の引用符がある場合、文字列を前方に検索します。存在する場合、文字列の外側にいます。ただし、この (ある程度扱いやすい) 正規表現は二重引用符のみを処理し、それらの中にエスケープされた引用符がない場合にのみ処理します。

次の正規表現は、エスケープされた引用符を含む一重引用符と二重引用符を正しく処理します。しかし、製品コードで誰かがこれを見つけた場合は、 The Daily WTFの特集記事が保証されることに同意していただけると思います。

Regex param = new Regex(
    @"[=:]
    (?=      # Assert even number of (relevant) single quotes, looking ahead:
     (?:
      (?:\\.|""(?:\\.|[^""\\])*""|[^\\'""])*
      '
      (?:\\.|""(?:\\.|[^""'\\])*""|[^\\'])*
      '
     )*
     (?:\\.|""(?:\\.|[^""\\])*""|[^\\'])*
     $
    )
    (?=      # Assert even number of (relevant) double quotes, looking ahead:
     (?:
      (?:\\.|'(?:\\.|[^'\\])*'|[^\\'""])*
      ""
      (?:\\.|'(?:\\.|[^'""\\])*'|[^\\""])*
      ""
     )*
     (?:\\.|'(?:\\.|[^'\\])*'|[^\\""])*
     $
    )", 
    RegexOptions.IgnorePatternWhitespace);

このモンスターの詳しい説明はこちら

于 2012-09-20T19:52:51.140 に答える
0

「正規表現の習得」を読んで、質問に対する一般的な解決策がない理由を理解する必要があります。正規表現はそれを任意の深さまで処理できません。エスケープ文字をエスケープし始めるか、エスケープ文字のエスケープをエスケープし始めるとすぐに、または...あなたは失われます。ユースケースには、正規表現ではなくパーサーが必要です。

于 2012-10-05T22:44:26.793 に答える