web-dev-qa-db-ja.com

正規表現C#-照合中に一致を抽出することは可能ですか?

たとえば、正しい形式を確認するために必要な文字列があるとします。例えばRR1234566-001(2文字、7桁、ダッシュ、1桁以上)。私は次のようなものを使用します:

        Regex regex = new Regex(patternString);
        if (regex.IsMatch(stringToMatch))
        {
            return true;
        }
        else
        {
            return false;
        }

これにより、stringToMatchpatternStringで定義されたパターンに従うかどうかがわかります。しかし、私が必要とするもの(そして後でこれらを抽出することになります)は、123456001-つまりstringToMatchの一部です。

これは正規表現の作成方法に関する問題ではないことに注意してください。私が求めているのは、「後で分割関数を使用せずに、値を同時に照合して抽出する方法はありますか?」

25
sarsnake

これを行うには、正規表現グループを使用できます。たとえば、次の正規表現は:

(\d\d\d)-(\d\d\d\d\d\d\d)

電話番号を次の正規表現と照合してみましょう。

var regex = new Regex(@"(\d\d\d)-(\d\d\d\d\d\d\d)");
var match = regex.Match("123-4567890");
if (match.Success)
    ....

一致する場合、最初の3桁は次の場所にあります。

match.Groups[1].Value

そして、次の7桁:

match.Groups[2].Value

追伸C#では、@ ""スタイルの文字列を使用して、バックスラッシュのエスケープを回避できます。たとえば、@ "\ hi \"は "\\ hi \\"と同じです。正規表現とパスに役立ちます。

P.S.2最初のグループは、予想どおりGroup [0]ではなくGroup [1]に格納されます。これは、Group [0]に一致した文字列全体が含まれているためです。

67
Andomar

代わりにグループ化と一致を使用してください。

つまり:

// NOTE: pseudocode.
Regex re = new Regex("(\\d+)-(\\d+)");
Match m = re.Match(stringToMatch))

if (m.Success) {
  String part1 = m.Groups[1].Value;
  String part2 = m.Groups[2].Value;
  return true;
} 
else {
  return false;
}

次のように、一致に名前を付けることもできます。

Regex re = new Regex("(?<Part1>\\d+)-(?<Part2>\\d+)");

このようなアクセス

  String part1 = m.Groups["Part1"].Value;
  String part2 = m.Groups["Part2"].Value;
17
cyberconte

括弧を使用して、文字のグループをキャプチャできます。

string test = "RR1234566-001";

// capture 2 letters, then 7 digits, then a hyphen, then 1 or more digits
string rx = @"^([A-Za-z]{2})(\d{7})(\-)(\d+)$";

Match m = Regex.Match(test, rx, RegexOptions.IgnoreCase);

if (m.Success)
{
    Console.WriteLine(m.Groups[1].Value);    // RR
    Console.WriteLine(m.Groups[2].Value);    // 1234566
    Console.WriteLine(m.Groups[3].Value);    // -
    Console.WriteLine(m.Groups[4].Value);    // 001
    return true;
}
else
{
    return false;
}
13
LukeH