Jyah
Jyah

Reputation: 25

Can I write a regular expression that checks two lengths are equal?

I want to match strings with two numbers of equal length, like : 42-42, 0-2, 12345-54321.

I don't want to match strings where the two numbers have different lengths, like : 42-1, 000-0000.

The two parts (separated by the hyphen) must have the same length.

I wonder if it is possible to do a regexp like [0-9]{n}-[0-9]{n} with n variable but equal?

If there is no clean way to that in one pattern (I must put that in the pattern attribute of a HTML form input), I will do something like /\d-\d|\d{2}-\d{2}|\d{3}-\d{3}|<etc>/ up to the maximum length (16 in my case).

Upvotes: 0

Views: 808

Answers (2)

David Gausmann
David Gausmann

Reputation: 1718

This is not possible with regular expressions, because this is neither a type-3 grammatic (can be done with regular expression) nor a type-2 grammatic (can be done with regular expressions, which support recursion).

The higher grammar levels (type-1 grammatic and type-0 grammatic) can only be parsed using a Turing machine (or something compatible like your programming language).

More about this can be found here: https://en.wikipedia.org/wiki/Chomsky_hierarchy#The_hierarchy

Using a programming language, you need to count the first sequence of digits, check for the minus and then check if the same amount of digits follows. Without the minus symbol, this would be a type-2 grammatic and could be solved using a recursive regular expression (even if the right sequence shall not contain digits), like this: ^(\d(?1)\d)$

So you need to write your own, non-regular-expression check code.

Upvotes: 2

Aaron
Aaron

Reputation: 24812

You should probably split the String around the separator and compare the length of both parts.

The tool of choice in regex to use when specifying "the same thing than before" are back-references, however they reference the matched value rather than the matching pattern : no way of using a back-reference to .{3} to match any 3 characters.

However, if you only need to validate a finite number of lengths, it can be (painfully) done with alternation :

  • \d-\d will match up to 1 character on both sides of the separator
  • \d-\d|\d{2}-\d{2} will match up to 2 characters on both sides of the separator
  • ...

Upvotes: 0

Related Questions