ilaunchpad
ilaunchpad

Reputation: 1313

Need to limit the number of character in a regular expression

I'm writing a regex. At this point it allows any number of digits:

^(([1-9]*)|(([1-9]*).([0-9]*)))$

How do I allow exactly 64 digits at total?

Upvotes: 3

Views: 8614

Answers (4)

Kash
Kash

Reputation: 9019

Try this regular expression:

^\d{64}$

Rubular link

But if you need a precision of 64 on a decimal number (as hinted from your regular expression in question), like the examples below,

235235236346345634644.4651346546213165498546516854985213242135355
235.2352363463456346444651346546213165498546516854985213242135355
23523523634634563464446513465462131654985.46516854985213242135355

which may have a variable number of digits before and after the decimal point but totaling to 64, then it is better to use string manipulation to remove the decimal point from the number and then applying the above regular expression for validation (or just validate the length of the string).


If you are really adamant on a regular expression, you could try this:

^((?:[1-9]\d{63})|(?:(?=[\d.]{65})(?![\d.]{66})(?:[1-9]\d*|0)\.\d*[1-9]))$

Breakdown:

  • (?:[1-9]{64}): this covers all digits and no decimal points.
  • | : the big logical OR.
  • (?=[\d.]{65}): Positive lookahead to allow only digits and points and ensure the total characters in input are not less than 65.
  • (?![\d.]{66}): Negative lookahead to allow only digits and points and ensure the total characters in input are not more than 65.
  • (?:[1-9]\d*|0): digits before the decimal should not have a preceding zero except when it is the only digit.
  • \.: enforces the decimal point to occur only once and not more (as was allowed by the lookaheads).
  • \d*[1-9]: ensures digits after decimal point do not end with zeroes.

This matches:

235235236346345634644.4651346546213165498546516854985213242135355
235.2352363463456346444651346546213165498546516854985213242135355
23523523634634563464446513465462131654985.46516854985213242135355
2352352363463456346444651346546213165498546516854985213242135355
0.465168549852132421353551545656456489155456651654654245646564558
2.465168549852132421353551545656456489155456651654654245646564558

And does not match:

0352352363463456346444651346546213165498546516854985213242135355
23523523634634563464446513465462131654985.46516854985213242100000
00.46516854985213242135355154565645648915545665165465424564656454
2352352363463456346444651346546213165498546516854985213242

(PS: Though I do not approve of this, it was fun trying it out.)

I tested on this Rubular link for different inputs.

@acheong87's positive lookahead in the comment helped me lead to this regular expression.

Upvotes: 1

mmdemirbas
mmdemirbas

Reputation: 9158

Regex

See it in action.

(?=^\d*\.?\d*$)^(\.?\d){64}$

Explanation

(?=^\d*\.?\d*$)     # Can contain maximum one dot in total between digits
^(\.?\d){64}$       # Match exactly 64 digits, dot is optional

The second line causes it to match 64 digits in total, optionally with any number of dots. The first line excludes strings with more than one dot. As a result, the regex gives you strings that consists of 64 digits and maximum 1 dot.

Matching samples

2352352363463456346444651346546213165498546516854985213242135355
.2352352363463456346444651346546213165498546516854985213242135355
235235236346345634644.4651346546213165498546516854985213242135355
235.2352363463456346444651346546213165498546516854985213242135355
23523523634634563464446513465462131654985.46516854985213242135355

Not-matching samples

235235236346345634644465134654621316549854651685498521324213535
2352352363463456346444651346546213165498546516854985213242135355.
..235235236346345634644465134654621316549854651685498521324213535
..2352352363463456346444651346546213165498546516854985213242135355
23523523.63463456346444651346546213165498.546516854985213242135355
23523523.63463456346444651346546213165498.54651685498521324213535

Upvotes: 3

Firas Dib
Firas Dib

Reputation: 2621

Try this regex: http://regex101.com/r/qM9mO8

/^(?:\d{64}|(?=.*\.)(?!.*\..*\.)[\d.]{64})$/gm

This regex will work for 64 consecutive digits or 63 digits and 1 dot.

I figured this was what you were looking for, considering your expression.

Good luck!

Upvotes: 0

crlanglois
crlanglois

Reputation: 3609

Replace the * with {n,m} where n is the minimum matches and m is the maximum matches, for example {0,64}

Or yes, you can do {64} if you want to match exactly 64 (no less).

See this reference Regular Expression Language - Quick Reference

Upvotes: 0

Related Questions