3

.NET正規表現を使用して、次のような文字列を解析しようとしています。

H3Y5NC8E-TGA5B6SB-2NVAQ4E0

分割を使用して以下を返します:H3Y5NC8E TGA5B6SB 2NVAQ4E0

各文字を特定の文字セットに対して検証するため(文字「I」、「O」、「U」、「W」はないことに注意してください)、string.Splitを使用することはできません。各グループの文字数はさまざまであり、グループ数もさまざまです。次の式を使用しています。

([ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8}-?){3}

これは、それぞれ8文字の3つのグループに正確に一致します。多かれ少なかれ試合に失敗します。これは、入力と正しく一致する限り機能します。ただし、Splitメソッドを使用して各文字グループを抽出すると、最終的なグループが取得されます。RegexBuddyは、キャプチャグループ自体を繰り返したので、繰り返しグループの周りにキャプチャグループを配置する必要があると文句を言います。ただし、これを実行しようとしても、目的の結果は得られません。私はこのような表現を試みてきました:

(([ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8})-?){4}

しかし、これは機能しません。

コードで正規表現を生成するので、グループの数だけ拡張できますが、より洗練されたソリューションを望んでいました。


文字セットにはアルファベット全体が含まれていないことに注意してください。これは、製品アクティベーションシステムの一部です。そのため、誤って数字やその他の文字として解釈される可能性のある文字はすべて削除されます。たとえば、文字「I」、「O」、「U」、および「W」は文字セットに含まれていません。

ハイフンは、ユーザーが上から入力する必要がないためオプションですが、ユーザーがコピー&ペーストを実行した場合は、ハイフンを入力できます。

4

9 に答える 9

5

ところで、 [ABCDEFGHJKLMNPQRSTVXYZ0123456789] 文字クラスを、より読みやすい減算文字クラスに置き換えることができます。

[[A-Z\d]-[IOUW]]

そのような 3 つのグループに一致させたいだけなら、正規表現でこのパターンを 3 回使用し、キャプチャされた 1、2、3 のサブグループを使用して新しい文字列を作成してみませんか?

([[A-Z\d]-[IOUW]]){8}-([[A-Z\d]-[IOUW]]){8}-([[A-Z\d]-[IOUW]]){8}

PHPでは、私は戻ります(私は.NETを知りません)

return "$1 $2 $3";
于 2008-08-25T12:01:15.183 に答える
3

あなたの質問と与えられた回答を見直した後、私はこれを思いつきました:

RegexOptions options = RegexOptions.None;
Regex regex = new Regex(@"([ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8})", options);
string input = @"H3Y5NC8E-TGA5B6SB-2NVAQ4E0";

MatchCollection matches = regex.Matches(input);
for (int i = 0; i != matches.Count; ++i)
{
    string match = matches[i].Value;
}

「-」はオプションなので付ける必要はありません。最後に {4} を何に使用していたのかわかりませんか? これにより、必要なものに基づいて一致が検索され、MatchCollection を使用して各一致にアクセスして文字列を再構築できます。

于 2008-08-25T02:53:26.793 に答える
3

私が求めていた答えを発見しました。ここに私の作業コードがあります:

    static void Main(string[] args)
    {
        string pattern = @"^\s*((?<group>[ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8})-?){3}\s*$";
        string input = "H3Y5NC8E-TGA5B6SB-2NVAQ4E0";
        Regex re = new Regex(pattern);
        Match m = re.Match(input);

        if (m.Success)
            foreach (Capture c in m.Groups["group"].Captures)
                Console.WriteLine(c.Value);
    }
于 2008-08-25T03:33:47.303 に答える
0

正規表現を使用する理由 グループが常に - で分割されている場合、Split() を使用できませんか?

于 2008-08-25T02:06:33.740 に答える
0

これが意図したものではない場合は申し訳ありませんが、文字列には常にグループを区切るハイフンがあり、正規表現を使用する代わりに String.Split() メソッドを使用できませんでしたか?

Dim stringArray As Array = someString.Split("-")
于 2008-08-25T02:09:28.053 に答える
0

次のパターンを使用できます。

Regex.Split("H3Y5NC8E-TGA5B6SB-2NVAQ4E0", "([ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8}+)-?")

ただし、結果の配列から空の文字列を除外する必要があります。MSDNからの引用:

複数の一致が互いに隣接している場合、空の文字列が配列に挿入されます。

于 2008-08-25T02:44:24.567 に答える
0

有効なブロックの特徴は何ですか? 本当に役立つためには、それを知る必要があります。

私の一般的な提案は、最初のステップで文字セットを検証してから、期待に基づいて別の方法で分割および解析することです。これが Web サイト/アプリにある場合は、フロント エンドで ASP Regex 検証を使用してから、バック エンドで分割できます。

于 2008-08-25T02:51:18.920 に答える
0

group(i).value を使用してグループの値を確認するだけの場合は、最後の値のみが取得されます。ただし、グループがキャプチャされたすべての時間を列挙したい場合は、以下に示すように group(2).captures(i).value を使用します。

system.text.RegularExpressions.Regex.Match("H3Y5NC8E-TGA5B6SB-2NVAQ4E0","(([ABCDEFGHJKLMNPQRSTVXYZ0123456789]+)-?)*").Groups(2).Captures(i).Value
于 2008-08-25T02:57:23.727 に答える
0

マイク、

文字グループ内で任意の文字セットを使用できます。すべてのグループをキャプチャするには、「+」修飾子を追加するだけです。私の以前の回答を参照してください。 [A-Z0-9] を必要なものに変更してください (つまり [ABCDEFGHJKLMNPQRSTVXYZ0123456789])

于 2008-08-25T02:57:40.480 に答える