1

We currently have a content compliance in place where by we monitor anything that contains a credit card number with no spaces (e.g 5100080000000000)

What we need is for a reg ex to pick up credit card numbers that are entered with spaces every 4 digits (eg: 5100 0800 0000 0000)

We've been looking at alternate reg exs but have not yet found one that works for both scenarios mentioned above.

The current reg ex we use is below

^((4\d{3})|(5[1-5]\d{2})|(6011)|(34\d{1})|(37\d{1}))-?\d{4}-?\d{4}-?\d{4}|3[4,7][\d\s-]{15}$

PaulG
  • 13,871
  • 9
  • 56
  • 78
user2386533
  • 11
  • 1
  • 1
  • 2
  • 2
    Why don't you just remove all of the spaces first? – Explosion Pills May 15 '13 at 15:44
  • I like using www.regexper.com to visualize these scenarios. Have you tried it? – DigCamara May 15 '13 at 15:44
  • @ExplosionPills. You use regex to find strings within a document. You can't remove *all* the spaces in a document without potentially invalidating lots of other data. Ideally you might remove spaces from credit cards within the document, but you need the regex to find the credit cards, so... – PaulG May 29 '13 at 09:36

5 Answers5

2

Just add optional /s? in where you already have the optional -?

So your regex becomes

^((4\d{3})|(5[1-5]\d{2})|(6011)|(34\d{1})|(37\d{1}))-?\s?\d{4}-?\s?\d{4}-?\s?\d{4}|3[4,7][\d\s-]{15}$
PaulG
  • 13,871
  • 9
  • 56
  • 78
1

It seems that you already accept a dash every four characters. Thus you can simply replace -? with [- ]? everywhere.

If you require the dashes or spaces to be consistent - that is, allow no grouping at all, or a dash every four characters, or a space every four characters, you can use a back reference to force the repetitions to be identical to the first match:

^(?:4\d{3}|5[1-5]\d{2}|6011|3[47]\d{2})([- ]?)\d{4}\1\d{4}\1\d{4}$

You will notice I removed the final 3[4,7]... which looked like an erroneous addition, apparently made when attempting to solve this problem partially. Also I changed the parentheses to non-grouping ones (?:...) or simply removed them where no grouping seemed necessary or useful, mainly because this makes it easier to see what the backreference \1 refers to. Finally, the 34.. and 37.. patterns had \d{1} where apparently \d{2} was intended (or if those particular series are only three digits before the first dash, the repetition {1} was just superfluous, but then the 3[4,7]... part would have been even more wrong!)

tripleee
  • 175,061
  • 34
  • 275
  • 318
1

Won't all these ideas blow up on you as soon as someone uses and AMEX card and enters 3 or 5 numbers instead of 4 in any one 'block'

Ron Robinson
  • 558
  • 1
  • 3
  • 8
0
((\d+) *(\d+) *(\d+) *(\d+))

That would be the general idea (and it even works!), you can polish it if you want. There is a great page to test your regexp live - http://rubular.com/

Tymoteusz Paul
  • 2,732
  • 17
  • 20
0

Try this:

(\d{4} *\d{4} *\d{4} *\d{4})
davide
  • 1,918
  • 2
  • 20
  • 30