捕获一个重复的组

时间:2008-08-25 01:59:45

标签: regex .net-2.0

我正在尝试使用.NET正则表达式解析如下所示的字符串:

H3Y5NC8E-TGA5B6SB-2NVAQ4E0

并使用Split返回以下内容:     H3Y5NC8E     TGA5B6SB     2NVAQ4E0

我根据特定的字符集验证每个字符(注意字母'I','O','U'和'W'不存在),因此使用string.Split不是一个选项。每组中的字符数可以变化,组的数量也可以变化。我使用以下表达式:

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

这将恰好匹配3组,每组8个字符。任何或多或少都会使比赛失败。 只要它正确匹配输入,这是有效的。但是,当我使用Split方法提取每个字符组时,我只得到最后一组。 RegexBuddy抱怨我已经重复了捕获组本身,我应该在重复组周围放置一个捕获组。但是,我没有尝试这样做能达到预期的效果。我一直在尝试这样的表达式:

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

但这不起作用。

由于我在代码中生成正则表达式,我可以通过组的数量来扩展它,但我希望有一个更优雅的解决方案。


请注意,字符集不包括整个字母。它是产品激活系统的一部分。因此,可以删除任何可能被意外解释为数字或其他字符的字符。例如字母'我','O','U'和& “W”不在字符集中。

连字符是可选的,因为用户不需要在顶部键入它们,但如果用户完成了副本,则它们可以在那里。糊。

9 个答案:

答案 0 :(得分: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";

答案 1 :(得分: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您可以访问每个匹配项来重建字符串。

答案 2 :(得分: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);
    }

答案 3 :(得分:0)

为什么要使用正则表达式?如果组总是被 - 分割,你不能使用Split()吗?

答案 4 :(得分:0)

很抱歉,如果这不是你想要的,但你的字符串总是有连字符分隔组然后而不是使用正则表达式你不能使用String.Split()方法?

Dim stringArray As Array = someString.Split("-")

答案 5 :(得分:0)

您可以使用此模式:

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

但是你需要从结果数组中过滤掉空字符串。 引自MSDN

  

如果多个匹配彼此相邻,则会在数组中插入空字符串。

答案 6 :(得分:0)

有效区块的定义特征是什么?我们需要知道,以便真正有所帮助。

我的通用建议,在第一步验证字符集,然后根据您的期望以单独的方法拆分和解析。如果这是在网站/应用程序中,那么您可以在前端使用ASP Regex验证,然后在后端将其分解。

答案 7 :(得分:0)

如果您只是使用group(i).value检查组的值,那么您将只获得最后一个。但是,如果要在捕获组的所有时间进行枚举,请使用group(2).captures(i).value,如下所示。

system.text.RegularExpressions.Regex.Match("H3Y5NC8E-TGA5B6SB-2NVAQ4E0","(([ABCDEFGHJKLMNPQRSTVXYZ0123456789]+)-?)*").Groups(2).Captures(i).Value

答案 8 :(得分:0)

麦克,

您可以在字符组中使用您选择的字符集。您只需添加“+”修饰符即可捕获所有组。请参阅我之前的回答,只需将[A-Z0-9]更改为您需要的任何内容(即[ABCDEFGHJKLMNPQRSTVXYZ0123456789])