2014-04-25 216 views
2

我有以下RegexC#匹配字母,数字和特殊字符的正则表达式

[A-Z]{2}[0-9]{4} 

,并与像这样的字符串完全符合:AB1234。但我必须改善这种Regex,以配合这些具体的规则:

  • 字符串必须只有2个锐器(##)每组(AB1234##AB1234
  • 它可以有8组串之间( AB1234##AB1234##AB1234##AB1234##AB1234##AB1234##AB1234##AB1234
  • 无论组数如何,最后一组在末尾都不能有锐利数字(##)。所以,如果我有3个组,它会看起来像这样:AB1234##AB1234##AB1234

如果我使用的样本串从第二个小点,我Regex将匹配的模式,但在这种情况下,它不会validade每组之间的字符。

任何人都可以帮助我改进这个正则表达式吗?

+0

为了提供有意义的反馈,我可能只是分割###,然后将简单的正则表达式应用到数组中的每个项目。 – Travis

+0

@Travis是的,你是对的,但我必须验证完整的字符串,而不是每个组。 –

回答

2

试试这个:

^([A-Z]{2}[0-9]{4}##){0,7}([A-Z]{2}[0-9]{4})$ 
1
([A-Z]{2}[0-9]{4}##){0,7}([A-Z]{2}[0-9]{4}) 
+0

如果我在最后放置了一个组,它将进行验证。实际上,它找到了2组。 –

+0

请澄清。这是正确的还是不正确? –

+1

不,我在最后添加了一个'## AB1234',并继续验证。如果我用'^'开始你的模式并用'$'完成,它就可以工作。 –

1

您可以结合RegexLINQ然后使用扩展方法是这样的:

public static bool Validate(this string source) 
{ 
    string pattern = "[A-Z]{2}[0-9]{4}"; 
    return !source.StartsWith("##") && 
      !source.EndsWith("##") && 
      source.Split(new[] {"##"}, StringSplitOptions.RemoveEmptyEntries) 
       .All(x => Regex.IsMatch(x, pattern)); 
} 

用法:

bool t1 = "AB1234##AB1234".Validate(); // true 
bool t2 = "AB1234##AB1234##AB1234".Validate(); // true 
bool t3 = "AB1234##AB1234##" // false 
+1

这是一个好主意,但我真的需要用正则表达式来做到这一点。 –

0
^(?:[A-Z]{2}[0-9]{4})(?:##(?:[A-Z]{2}[0-9]{4})){0,7}$ 
    ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^^ 
      (1)     (2)   (3) 
  1. 匹配至少一个以两个大写字母开头的字符串,后跟4个十进制数字。
  2. 可选地,按照##从0到7次重复第一次匹配。

结果:*指示匹配)

* AB1234 
    AB1234x 
* AB1234##AB1234 
* AB1234##AB1234##AB1234 
    AB1234##AB1234##AB1234x 

live demo

注:这个答案和this other answer很相似。然而,这里的答案始于假设至少有一个序列AB1234存在。然后它允许的可能性它被##AB1234跟随0到7次。最后,这两个正则表达式都很好。这归结于个人偏好。

另请注意,我使用非捕获组(?:...)来避免创建在此情况下不需要的捕获组的不必要开销。 (捕获组也被称为后向引用。)

相关问题