2017-10-29 2 views
0

のは、私はこのような文字列があるとしましょう:正規表現:オプションのパターンを優先する

555 3553 666 555 

そしてこの

var pat = new Regex("3?553?"); 

のような正規表現上の文字列が一致したときに返さpat.Match(mystring)結果はとなります"55" 可能な場合は返される結果が「3553」である必要があり、そうでない場合は結果が「55」になります。次のように:3?はオプションであり、必ずしもそうである必要はありませんが、その場合は常に最初に一致します。

だから、これ555 3553 666 555は3553

を返し、この222 5555 777は、2つの別々の正規表現の定義を使用せずに55

を達成するのは、このことは可能ですが返されますか?

ありがとうございます。

+0

これは重複していない - 単語境界のアンカーが第二に、 '55'の所望の一致が許可されませんので、少なくともいないリンクの質問の場合。 –

答えて

0

もしそうなら、あなたはマッチよりも優先度を使いたいと思う!私は、コードの下に考えるあなたを助けることができます。

var matches = Regex.Matches(txt, @"(?<G1>3553)|(?<G2>55)").OfType<Match>(); 
var res = matches 
     .GroupBy(x => x.Success) 
     .Select(x => 
      new { 
        Success = x.Key, 
        G = !string.IsNullOrEmpty(x.Max(w => w.Groups["G1"].Value)) 
         ? x.Max(w => w.Groups["G1"].Value) 
         : x.Max(w => w.Groups["G2"].Value) 
       }) 
     .SingleOrDefault(); 

C# Demo

0

あなたの正規表現は55と一致します。優先順位とは関係ありません。

あなたがここで望んでいるのは、最も長い試合をすることだと思います。 Matchesを使用してすべての一致を取得し、Lengthをチェックして最長のものを取得する必要があります。

var matches = Regex.Matches("555 3553 666 555", "3?553?"); 
var longestMatch = matches.Cast<Match>().OrderByDescending(x => x.Value.Length).First().Value 
+0

問題:一致は重複できません。 '5553533'で試してください。 –

0

正規表現エンジンは、常に左から右の文字列を通過します(左から右のスクリプトを想定しています)。あなたの場合、最初の2文字は正規表現と一致します。したがって、それは返します。

最初の試合後に停止する代わりに、すべての試合を行い、最長の試合を選択する必要があります。しかし、注意点があります。正規表現のマッチは重複できません(すべての文字は1回だけ一致させることができます)。したがって、

55553553 

ような文字列であなたの正規表現は55553、および553を返します。

ソリューションは、キャプチャグループと組み合わせて、lookahead assertionを使用することです:

var pat = new Regex("(?=(3?553?))", "g"); 

とそのすべての試合

var match = pat.exec(subject); 
while (match != null) { 
    // matched text: match[1], add that to an array 
    } 
    match = pat.exec(subject); 
} 

を取得するには、その後、最長一致を選択してください。