Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split credit card number into 4 chunks using Regex lookahead?

I want to chunk a credit card number (in my case I always have 16 digits) into 4 chunks of 4 digits.

I've succeeded doing it via positive look ahead :

var s="4581458245834584";
var t=Regex.Split(s,"(?=(?:....)*$)");
Console.WriteLine(t);

But I don't understand why the result is with two padded empty cells:

enter image description here

I already know that I can use "Remove Empty Entries" flag , But I'm not after that.
However - If I change the regex to (?=(?:....)+$) , then I get this result :

enter image description here

Question

Why does the regex emit empty cells ? and how can I fix my regex so it produce 4 chunks at first place ( without having to 'trim' those empty entries )

like image 417
Royi Namir Avatar asked Apr 23 '17 11:04

Royi Namir


1 Answers

But I don't understand why the result is with two padded empty cells: Let's try breaking down your regex.

Regex: (?=(?:....)*$)

Explanation: Lookahead (?=) for anything 4 times(?:....) for zero or more times. Just looking ahead and matching nothing will match zero width.

Since you are using * quantifier which says zero or more it matches first zero width at beginning or string and also at end of string.

Visualize it from this snapshot of Regex101 Demo

[Zero Width visualization.[2]

So How can I select only those 3 splitters in the middle ?

I don't know C# very well but this 3 step method might work for you.

  1. Search with (\d{4}) and replace with -\1. Result will be -4581-4582-4583-4584. Demo

  2. Now replace first - by searching with ^-. Result will be 4581-4582-4583-4584. Demo

  3. At last search for - and split on it. Demo. Used \n to substitute for demo purpose.

Alternative Solution Inspired from Royi's answer.

Regex: (?=(?!^)(?:\d{4})+$)

Explanation:

(?=              // Look ahead for
   (?!^)         // Not the start of string
   (?:\d{4})+$   // Multiple group of 4 digits till end of string
)

Regex Tracking

Since nothing is matched and only lookaround assertions are used, it will pinpoint Zero width after a group of 4 digits.

Regex101 Demo

like image 151
Rahul Avatar answered Sep 27 '22 22:09

Rahul