Reputation: 45
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
\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:
1234 5678 9001 0000 1111
1234-5678-9001-0000-1111
1234 5678 9001 00001 111
1234-5678-9001-00001-111
The RegEx will include some parts of the numbers and marked them as matched. Which is not what we expected. You can see it live at regex101.com
Can anyone help us?
Upvotes: 1
Views: 953
Reputation: 626903
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(?:
- outer non-capturing group:
(?:\d[ -]*?){17,}
- 17 or more digits optionally separated with 0+ spaces or -
|
- or((?:\d[ -]*?){13,16})
- Group 1 matching 13 to 16 occurrences of a digit followed with 0+ spaces or/and hyphens)
- end of the outer group to match the strings within word boundaries only\b
- a word boundaryC# code:
var values_we_need = Regex.Match(our_text, @"\b(?:(?:\d[ -]*?){17,}|((?:\d[ -]*?){13,16}))\b")
.Cast<Match>()
.Select(m => m.Groups[1].Value)
.ToList();
Upvotes: 3
Reputation: 29431
Since it appears that your have a separator you can split the entry then test it over this regex ^(?:\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();
}
}
Upvotes: 0