简体   繁体   English

RegEx找到信用卡模式并没有排除超过16位的信用卡模式

[英]RegEx to find credit card pattern did not exclude the ones that has more than 16 digits

We are building a pattern matcher to find credit card pattern (not necessarily a valid one) from a string. 我们正在构建模式匹配器,以便从字符串中查找信用卡模式(不一定是有效模式)。 Currently we are using this regex from regular-expressions.info 目前我们正在使用来自regular-expressions.info的这个正则表达式

\b(?:\d[ -]*?){13,16}\b

The regex works fine for unless it's trying to exclude invalid numbers that are longer than 16 digits and has space or dash delimiter such as: 正则表达式工作正常,除非它试图排除长度超过16位的无效数字并且具有空格或破折号分隔符,例如:

1234 5678 9001 0000 1111 1234 5678 9001 0000 1111
1234-5678-9001-0000-1111 1234-5678-9001-0000-1111
1234 5678 9001 00001 111 1234 5678 9001 00001 111
1234-5678-9001-00001-111 1234-5678-9001-00001-111

The RegEx will include some parts of the numbers and marked them as matched. RegEx将包含数字的某些部分并将其标记为匹配。 Which is not what we expected. 这不是我们的预期。 You can see it live at regex101.com 您可以在regex101.com上看到它

Can anyone help us? 有人可以帮助我们吗?

If you need to skip something and only get something else, it is easier to match what you want to skip and match and capture what you need to keep. 如果您需要跳过某些内容并且只获取其他内容,则可以更轻松地匹配您想要跳过的内容并匹配并捕获您需要保留的内容。

Use 采用

\b(?:(?:\d[ -]*?){17,}|((?:\d[ -]*?){13,16}))\b

See the regex demo . 请参阅正则表达式演示

Details 细节

  • \\b - a word boundary \\b - 单词边界
  • (?: - outer non-capturing group: (?: - 外部非捕获组:
    • (?:\\d[ -]*?){17,} - 17 or more digits optionally separated with 0+ spaces or - (?:\\d[ -]*?){17,} - 17个或更多个数字可选地用0+空格分隔或-
    • | - or - 要么
    • ((?:\\d[ -]*?){13,16}) - Group 1 matching 13 to 16 occurrences of a digit followed with 0+ spaces or/and hyphens ((?:\\d[ -]*?){13,16}) - 第1组匹配13到16次出现的数字后跟0+空格或/和连字符
  • ) - end of the outer group to match the strings within word boundaries only ) - 外部组的结尾仅匹配单词边界内的字符串
  • \\b - a word boundary \\b - 单词边界

C# code: C#代码:

var values_we_need = Regex.Match(our_text, @"\b(?:(?:\d[ -]*?){17,}|((?:\d[ -]*?){13,16}))\b")
    .Cast<Match>()
    .Select(m => m.Groups[1].Value)
    .ToList();

Since it appears that your have a separator you can split the entry then test it over this regex ^(?:\\d[ -]*?){13,16}$ : 由于看起来您有一个分隔符,您可以拆分该条目,然后在此正则表达式上进行测试^(?:\\d[ -]*?){13,16}$

static void Main(String[] args)
{
    var myInput = "5000123456789001, 5000-1234-5678-9001, 5000 1234 5678 9001, 50001234567890010000, 5000-1234-5678-9001-0000, 5000 1234 5678 9001 0000, 5000-1234-5678-90010-000, 5000 1234 5678 90010 000";

    foreach (var cardNumber in SeparateInput(myInput, ','))
    {
        Console.WriteLine($"'{cardNumber}' is {(IsThisNumberValid(cardNumber) ? "valid" : "not valid" )}");
    }

    Console.ReadLine();
}

private static bool IsThisNumberValid(string input)
{
    return Regex.IsMatch(input, @"^(?:\d[ -]*?){13,16}$");
}

private static IEnumerable<string> SeparateInput(string input, char separator)
{
    foreach (var splitted in input.Split(new []{separator}, StringSplitOptions.RemoveEmptyEntries))
    {
        yield return splitted.Trim();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM