新的Mercosul牌照正则表达式

时间:2015-04-23 21:16:40

标签: c# .net regex

新的Mercosul牌照有以下规则:

  • 必须有7个字母数字,其中:
    • 4是字母(A-Z)
    • 3是数字(\ d)
  • 无论如何,字母和数字都可以洗牌。

以下文字有效:AB123CD,1A2B3CD,123ABCD,ABCD123

这些都是无效的:ABC1234D,ABCDE12,ABC123等

我知道我可以通过代码检查字符串大小并计算数字和字母来实现这一点,但这个问题让我想知道是否也可以通过Regex实现。

我所能想到的就是产生所有可能性,如(\ d {3} [A-Z] {4}),(\ d {2} [A-Z] {4} \ d)并使用|加入他们,鉴于大量的组合,任何其他的想法,这是不实际的?或者这只是Regex不行的情况?

在答案后编辑:

正如@stribizhev发布的那样,这是一个典型的Ahead用例。

我发现这个link是一个非常有用的来源

here's an example关于如何使用lookarounds执行密码验证

3 个答案:

答案 0 :(得分:9)

您可以使用以下正则表达式进行验证:

^(?=(?:.*[0-9]){3})(?=(?:.*[A-Z]){4})[A-Z0-9]{7}$

<强>解释

  • (?=(?:.*[0-9]){3}) - 正面预测以检查3位数字
  • (?=(?:.*[A-Z]){4}) - 正面预测以检查4个字母
  • [A-Z0-9]{7} - 由7个字母数字符号组成的实际字符串(不包括属于_模式的\w

由于锚点(^$),应传递单个字符串以通过此测试。

您可以通过添加适当的选项来添加不区分大小写的匹配。

在Expresso中测试:

enter image description here

答案 1 :(得分:1)

对于这种事情,从另一个方向(在psedudo代码中)看它会更容易:

letters = regex(s/[^a-z]//, license_plate);
numbers = regex(s/[^\d]//, license_plate);

if (length(letters) == 4) && (length(numbers) == 3)) {
   plate is ok
}

答案 2 :(得分:0)

我不喜欢风格。

bool CheckPlate(string str)
{
    int let = 0;
    int dig = 0;
    foreach (ch letter in input)
    {
        let += (int) IsLetter(ch);
        dig += (int) IsDigit(ch);   
    }
    if(let == 4 && dig == 3 && str.Lenght() == 7)
        return true;
    else
      return false;
}