2017-06-13 8 views
-3

私は、フォームはparamIdがパラメータのIDで、paramValueはほとんど可能性はparamIdの(私たちが含まれていないいないものである正規表現:ハンドルパラメータ

(<paramID><paramValue>)*(LastValue)* 

を持っているいくつかのテキストを解析したいですそれを明白に解析することができる)。注意すべき

主なものは以下のとおりです。

  1. 最初はparamIdは任意です。
  2. paramValuesはグループ化を使用できます。グループ化の中の何かは、たとえparamIDのようであっても、1つのトークンとして扱われます。
  3. 各paramValueは最後を除いて貪欲に解析されます。これは遅れて解析されます。

はparamId = "\s-[^\s\[\(\{\\""]+" paramValue =基本的にはparamIdの間に何である(私は、これは同じパラメータの異なる順序が異なる解釈を持っていますが、解釈自体が常に明確に定義され、容易に理解されます実現します)。これにはparamIDのようなものが含まれているかもしれないが、それらは "グループ"の内部にあるので、無視する必要がある。

例えば、

First Param Value -p1 Second Param Value -p2[Third-Param-Value] -X "-Fourth -Param -Value" -pl LastParamValue Last Value 

は明白な方法で解析されるべきです。

+0

何が質問ですか? –

+0

@ShaiCohenそれは明白ではありませんか?私はそれを行う正規表現が必要です。 – AbstractDissonance

答えて

1

私は次のように表現をトークン化することをお勧め:カッコ内

  • グループ。
    • balanced groupsを使用すると、[...]の場合は(?>(?'o'\[)[^][]*)+(?>[^][]*(?'-o'\]))+のようになります。これにより、グループのネストが可能になります。
    • 同様の表現は、一連のスペース
    • および価値部品が先行ダッシュ始まる
    • パラメータ名引用符で囲まれたグループ(可能とが内引用符をエスケープ){...}(...)
  • ために製造することができます空白で囲まれた非空白文字。これらは、最後のパラメータを除くすべてのパラメータに連結されます。最後のパラメータの場合は最初の値のみが使用され、その他の場合は最後の値が構成されます。

だからトークナイザ式は次のとおりです。

var paramDict = new Dictionary<string, string>(); 
var currParam = "<FIRST>"; 
var currValues = new List<string>(); 
var lastParam = currParam; 
foreach (var token in tokensRegex.Matches(expression) 
    .Cast<Match>().Select(m => m.Groups["token"].Value)) 
{ 
    if (token.StartsWith("-")) 
    { 
     // This is a paramater name. Store collected value 
     // for the previous one and reset currXXX 
     if (currParam == "<FIRST>" && currValues.Count == 0) 
     { 
      // The first param has its own name so don't add the default one. 
      // Set the param name only 
      currParam = token; 
     } 
     else 
     { 
      paramDict.Add(currParam, string.Join("", currValues)); 
      currParam = token; 
      currValues = new List<string>(); 
     } 
    } 
    else 
    { 
     currValues.Add(token); 
    } 
} 

// If the last value list has more that one item, set the first item 
// as the last param value and the rest as the last value. 
if (currValues.Count > 1) 
{ 
    paramDict[currParam] = currValues[0]; 
    paramDict["<LAST>"] = string.Join("", currValues.Skip(1)); 
} 

デモ:https://dotnetfiddle.net/bg1jxp

(?x) 
    \s*(?<token> (?>(?'o'\[)[^][]*)+(?>[^][]*(?'-o'\]))+)\s* # balanced [...] group 
| \s*(?<token> (?>(?'o'\{)[^{}]*)+(?>[^{}]*(?'-o'\}))+)\s* # balanced {...} group 
| \s*(?<token> (?>(?'o'\()[^()]*)+(?>[^()]*(?'-o'\)))+)\s* # balanced (...) group 
| \s*(?<token> "(?:\\"|[^"])*")\s* # quoted group with possible escaped quotes within 
| \s*(?<token> -[^\s"({[]+)   # parameter name 
| (?<token> \s*\S+\s*)    # parameter value part not in group/quotes 

Demo

はその後、我々は、トークンをスキャンし、適切にパラメータと値のペアを収集する必要があります