I have a credit card number that will contain up to 16 digits and I am trying to split it apart: Ex. (1234567891234567)
to: (1234 5678 9123 4567)
.
I'm still a pretty big RegExp newb, but I have ^(\d{4})(\d{4})?(\d{4})?(\d{4})?
The regex will match when there is exactly 4 numbers for at least 2 groups (1234 5678)
but will fail on (1234 56)
If I add {2,4}
I get things like (1234 56 78)
which I don't want.
Any help is greatly appreciated
UPDATE 1:
The goal is to have the credit card number split apart as the user is typing it:
So 123456
would automatically become: 1234 56
, etc. etc.
UPDATE 2: The easiest way to explain what I am trying to do is here: https://stripe.com/docs/tutorials/checkout and click on Pay with Card, then type in the "credit card" field, you will see the numbers shift as you are typing.
I was going to just delete this since my answer isn't exactly what I was looking for in this question, but I can't delete it so:
I was able to create the desired functionality through the following function(s):
(Here is a Working Example: http://jsfiddle.net/7vH6T/ )
var creditcards = {
list:[
{
brand: 'American Express',
image: '/images/creditcards/american-express.png',
verification: '^3[47][0-9]',
separation: '^([0-9]{4})([0-9]{6})?(?:([0-9]{6})([0-9]{5}))?$',
hidden: '**** ****** *[0-9][0-9][0-9][0-9]',
accepted: true,
length: 15
},
{
brand: 'MasterCard',
image: '/images/creditcards/mastercard.png',
verification: '^5[1-5][0-9]',
separation: '^([0-9]{4})([0-9]{4})?([0-9]{4})?([0-9]{4})?$',
hidden: '**** **** **** [0-9][0-9][0-9][0-9]',
accepted: true,
length: 16
},
{
brand: 'Visa',
image: '/images/creditcards/visa.png',
verification: '^4[0-9]',
separation: '^([0-9]{4})([0-9]{4})?([0-9]{4})?([0-9]{4})?$',
hidden: '**** **** **** [0-9][0-9][0-9][0-9]',
accepted: true,
length: 16
},
{
brand: 'Discover',
image: '/images/creditcards/discover.png',
verification: '^6(?:011|5[0-9]{2})[0-9]',
separation: '^([0-9]{4})([0-9]{4})?([0-9]{4})?([0-9]{4})?$',
hidden: '**** **** **** [0-9][0-9][0-9][0-9]',
accepted: false,
length: 16
},
{
brand: 'Diners Club',
image: '/images/creditcards/diners-club-international.png',
verification: '^3(?:0[0-5]|[68][0-9])[0-9]',
separation: '^([0-9]{4})([0-9]{4})?([0-9]{4})?(?:([0-9]{4})([0-9]{4})([0-9]{2}))?$',
hidden: '**** **** **[0-9][0-9] [0-9][0-9]',
accepted: false,
length: 14
},
{
brand: 'JCB',
image: '/images/creditcards/jcb.png',
verification: '^(?:2131|1800|35[0-9]{3})[0-9]',
separation: '^([0-9]{4})([0-9]{4})?([0-9]{4})?([0-9]{4})?$',
hidden: '**** **** **** [0-9][0-9][0-9][0-9]',
accepted: false,
length: 16
}
],
active:null
};
//On Keydown
$('input[name="creditcard"]').keydown(function(e){
//Preset Data
var card = $(this).val().replace(/[^0-9]/g,''),
trim = $.trim( $(this).val().slice(0,-1) );
//Find the Credit Card
for( var i=0; i<creditcards.list.length; i++ ){
//Check the Type
if(card.match( new RegExp(creditcards.list[i].verification) )){
//Set the Active Card
creditcards.active = i;
//Add Credit Card Icon
if( $(this).next('img').length == 0 ){
//Remove any possible Error
$(this).next('small').remove();
//Add the Image
$(this).after('<img src="'+creditcards.list[i].image+'" alt="'+creditcards.list[i].brand+'" style="height:20px; position:relative; top:5px;" />');
}
//If the Credit Card is NOT accepted, Show the Error
if( !creditcards.list[i].accepted && $(this).nextAll('small').length == 0 ){
//Show Error
$(this).next('img').after('<small style="margin-left:5px; color:#F00;">'+'Creditcard Not Accepted'+'</small>');
}
//End the Loop
break;
}
}
//Show Invalid Card
if( creditcards.active == null && card.length > 4 && $(this).nextAll('small').length == 0 ){
//Show Error
$(this).after('<small style="margin-left:5px; color:#F00;">'+'Invalid Credit Card'+'</small>');
}
//Preset they Key
key = creditcards.active !== null? creditcards.active : 1 ;
//If the Last Character is a String, Remove it
if( e.keyCode == 8 && trim != $(this).val().slice(0,-1) ){
//Set the New Value
$(this).val( trim );
//Stop from Completing
e.preventDefault();
//Return
return;
}
//Limit the Length of the Card, Allow Keys
if( card.length >= creditcards.list[ key ].length && $.inArray(e.keyCode, [37, 38, 39, 40, 46, 8, 9, 27, 13, 110, 190]) === -1 && !e.metaKey && !e.ctrlKey ){
e.preventDefault();
return;
}
//Add a Space if the Regex Passes
if( new RegExp(creditcards.list[ key ].separation).exec( card ) && e.keyCode >= 48 && e.keyCode <= 57 ){
$(this).val( $(this).val() + ' ' );
}
//Return
return;
});
//On Key up Ensure Card is Validated
$('input[name="creditcard"]').keyup(function(e){
//Get the Card
var card = $(this).val().replace(/[^0-9]/,'');
//Check if the Card is Active
if( creditcards.active !== null && !card.match( new RegExp(creditcards.list[ creditcards.active ].verification) ) ){
//Remove any Existing Error
$(this).nextAll('small').remove();
//If Not, Remove the Icon
$(this).next('img').remove();
//Set Active to NULL
creditcards.active = null;
}else
if( card.length < 4 ){
//Remove Invalid Card Error
$(this).next('small').remove();
}
});
$('input[name="creditcard"]').on('paste',function(e){
//Save the Element
var el = this;
//Set Timeout to Run Function
setTimeout(function(){
//Save the Card
var card = $(el).val().replace(/[^0-9]/g,'');
//Remove all but numbers
$(el).val( card );
//Prepare the Keydown Event
var e = jQuery.Event('keydown',{
which: 37,
keyCode: 37
});
//Trigger Keydown
$(el).trigger(e).promise().done(function(e){
//Preset they Key
key = creditcards.active !== null? creditcards.active : 1 ;
//Force the Card Length
card.substr( 0 , creditcards.list[ key ].length );
//Separate the Card
var separation = new RegExp(creditcards.list[ key ].separation).exec( card ),
storage = '';
//Find the Closest Separation Point
while( !separation && card.length > 1 ){
storage = card.charAt( card.length - 1 );
card = card.slice(0,-1);
separation = new RegExp(creditcards.list[ key ].separation).exec( card );
}
//If there was a Separation
if( separation ){
//A Holder for all of the Separation that is defined
var separated = [];
//Remove all Undefined Separation Fields
for( var i=0; i<separation.length; i++){
if( typeof separation[i] != 'undefined' ) separated.push( separation[i] );
}
//Build the String
var string = separated.slice(1).join(' ') + (storage!=''? ' '+storage : '' )
//Add the Separated Value
$(el).val( string )
}
//End $(el).trigger(e).promise().dome(function(e){
});
//End setTimeout(function(){
},0);
//End $(input[name="creditcard"]
});
Simply replace every four digits in the original string with the same digits followed by a space, like this
console.log("123456789101112".replace(/(\d{4}(?!\s))/g, "$1 "));
I think there are many developers who implement credit card transaction with Stripe. Here is the example. Also, the accepted answer is too complicated and other ones won't work for "American Express".
let cardNumber;
let brand = Stripe.card.cardType(value)
if (brand === "American Express") {
let tempVal = value.replace(/\s/g, '');
cardNumber = (tempVal.slice(0,4).replace(/(.{4})/g, '$1 ') +
tempVal.slice(4,10).replace(/(.{6})/g, '$1 ') +
tempVal.slice(10,15)).trim();
} else {
cardNumber = value.replace(/\s/g, '').replace(/(.{4})/g, '$1 ').trim();
}
return cardNumber
I use helper function of stripe.js only for detecting the brand. So, you can use the rest even you are not using Stripe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With