2012-02-13 13 views
3

私は入力テキストファイルを解析するプロジェクトに取り組んでいます。私はC#を学んでいます。私はそれをたくさんやっているマッチと正規表現の使用

string MyMatchString = @"a pattern to match"; 
Match MyMatch = Regex.Match(somestringinput, MyMatchString); 
if (MyMatch.Succes) 
{ 
    DoSomething(MyMatch.Value); 
} 

:私は必要な情報を選び出すための私の現在の方法は、のようなものです。私は試合と成功のテストを1つのステップで組み合わせることができるようにしたいと考えています。クラスリストを見て、RegexはIsMatch()メソッドを持っていますが、一致した値にアクセスすることはできません(成功したと仮定して)。私はそのためにMatchインスタンスが必要だと思います。試しました

if ((Match MyMatch = Regex.Match(somestringinput, MyMatchString).Success) 

もちろん、コンパイルエラーが発生しました。

私は、マッチパターンを取る静的メソッドを考えています。そして、入力はブールを返します。それから、私は成功のためにテストすることができます。

+0

あなたはあなた自身の質問に答えました... – Tudor

答えて

1

さてあなたは、あなたにいくつかの力を与えるだろう正規表現のための拡張メソッドを書くことができます。トリックは正規表現マッチを2回実行することなく実行しています(これはテストされておらず、Regexオブジェクトが動作する必要があるという点であなたの考えとは異なります)。

public static class RegexExtensions { 
    public static bool GetMatch(this Regex regex, string input, out string matched) { 
     Match match = regex.Match(input); 
     if (match.Success) { 
      matched = match.Value; 
      return true; 
     } 
     matched = null; 
     return false; 
    } 
} 

だからあなたはあなたがちょうどそうでない場合、故障の場合、文字列にnullを返し、ブール値と出力パラメータを省略することを好むかもしれません

string matched; 
Regex regex = new Regex(pattern); 
if (regex.GetMatch(inputstring, matched)) 
{ /* do something with 'matched' */ } 
else 
{ /* no match, 'matched' is null */ } 

ような何かをしたいです。

+0

+1元のコードのセマンティクスを少し変更しますが、これは最もエレガントなアプローチです。静的な拡張メソッドを定義できないことは残念です。 – Tudor

+0

良い提案。私がこのアプローチで見ることができる1つの問題は、Matchから得られるものすべてが単一の文字列値であることです。特定のユースケースでは問題ありませんが、それほど柔軟性はありません。正規表現の2つの値が必要な場合はどうなりますか? –

+0

このアプローチのようなものは、私が考えていたものです。私はこれをforeachで微調整し、複数の一致のための文字列のリストを返すことができます。それは、MatchCollectionのためのオーバーロードまたはオーバーロードです。 C#は参照型を参照渡しするため、文字列を返す代わりにboolの戻り値もテストします。 RegExの代わりにMatchで渡すこともできます。戻り値の型がboolで、このメソッドを実行して一致が成功した場合、渡された一致が一致の結果を指すように変更されます。いいえ? –

3

あなたが唯一の一致(または.Take(1)を使用)をしたい場合、オプションbreakを追加するforeach

string MyMatchString = @"a pattern to match"; 
foreach (Match match in Regex.Matches(somestringinput, MyMatchString)) 
{ 
    DoSomething(match.Value); 
} 

を使用することができます

0

あなただけのブール値としての答えをしたいし、それがいけない保存したくない場合それを格納するために変数マッチを使用します。あなたはちょうどあなたがこのようにしたいブール値を取得するためにRegex.Matchを使用することができます。

if (Regex.Match("a", MyMatchString).Success) { }; 
+0

その場合、なぜIsMatchを使用しないのですか? –

+0

彼はそれを使うこともできます。 – NoviceMe

1

TryParseTryGetValueで使用される「試行」規約を実装できます。

public static bool TryMatch(string input, string pattern, out Match match) 
{ 
    var m = Regex.Match(input, pattern); 
    if(m.Success) 
    { 
     match = m; 
    } 
    return m.Success; 
} 

// usage 
string myMatchString = @"a pattern to match"; 
Match result = null; 
if(TryMatch(somestringinput, myMatchString, out result)) 
{ 
    DoSomething(result.Value); 
} 

また、あなたはActionFunc代表団を受け入れる高階関数を作成することができます。

public void ActionOnMatch(string input, string pattern, Action<string> action) 
{ 
    var m = Regex.Match(input, pattern); 
    if(m.Success) 
    { 
     action(m.Value); 
    } 
} 

public TResult FuncOnMatch<TResult>(string input, string pattern, 
    Func<string, TResult> func) 
{ 
    var m = Regex.Match(input, pattern); 
    if(m.Success) 
    { 
     return func(m.Value); 
    } 
    else 
    { 
     return default(TResult); 
    } 
} 

/// usage 
string pattern = @"a pattern to match"; 
ActionOnMatch(input, pattern, DoSomething); 
var result = FuncOnMatch<string>(input, pattern, (val) => val); 
0

成功のためのテストと結果の使用は、設計上、別々の手順です。その周りには方法があるかもしれませんが、フレームワークと戦って、おそらくあなたのコードを少し小さくします他の開発者のためにが読みにくくなります。

ファイルを解析する場合は、Linqを使用して別の方法を検討することもできます。 DoSomethingが何を意味しているかによっては、少なくともコードを少し面倒にするかもしれません。

Regex re = new Regex(@"(?<prop1>pattern part 1)(?<prop2>pattern part 2)"); 

var goodLines = 
    from line in File.ReadAllLines(inputFile) 
    let m = re.Match(line) 
    where m.Success 
    select new { 
     Prop1 = m.Groups["prop1"].ToString(), 
     Prop2 = m.Groups["prop2"].ToString() 
    } 

foreach (var goodLine in goodLines) { 
    DoSomething(goodLine); 
} 

ここでは、正規表現の中に名前のキャプチャグループを定義し、匿名型を投入するために、これらの名前のキャプチャを使用しています。次に、Linq式で返された匿名オブジェクトのコレクションをループします。

+0

私はLINQについて考えましたが、ファイルのこのセクションでは私が検索する3つのマッチがあります。もし私が見つけたら、私は3つの異なることのうちの1つを行います。私は3のそれぞれのためにモンスターのマッチを書くことができました(そして、持っている)が、それらはパターン、特にそこにあるかもしれないかもしれないかもしれないいくつかの権利を得るのが難しいです。 –

+0

一番上のレベルのパターンが見つかると、一致するサブレベルのパターンがあります。可能であれば20行にマッチする正規表現を書くのは良い考えではないでしょう。独立したLINQステートメントは、サブレベルの一致がトップレベルに対応することを保証しません。 –