Regex expression for all positive rational numbers with no leading zeros(not including decimal form)

Viewed 95

I have this expression:

([-][1-9]*[/][-][1-9]*|[1-9]*[/][1-9]*|[1-9]+\d*)

and my thought process around it was there was three cases.

When the rational number is in the form a/b:

[1-9]*[/][1-9]*

When the rational number is in the form -a/-b (turns out to be positive because both numerator and denominator are negative):

[-][1-9]*[/][-][1-9]*

When the rational number is an integer (because all integers are rational numbers):

[1-9]+\d*

Is there any way to make this regular expression shorter?

Especially where I have the two cases where its either a/b or -a/-b, is there any way to combine those two cases into one case?

2 Answers

Your regex needs some fixing. It doesn't match -10/-20 but matches invalid numbers like

/
-/-
-23/

and allows for partial matches which may or may not be desirable. For example, it makes a match on 1/2 for the input -1/2, or 123 in 0123, etc.

You also have a lot of square brackets [] that aren't required actually. [] are used when you have multiple characters to match at a specific position, you should use a single \ to escape special characters, like, \|.

a/b or -a/-b, is there any way to combine those two cases into one case?

Yes, using a backreference \n you can match on b or -b depending on whether a match for a or -a was found previously i.e. -b becomes invalid if -a was not found.

Try the following regex

^((-)?[1-9]\d*\/\2[1-9]\d*|[1-9]\d*)$

[1-9]\d* allows numbers to have 0s anywhere except the beginning, ^ and $ disable partial matches, and \2 is a backreference that captures the presence of the - negative sign.

Matches

1/2
23/56
-1/-2
-10/-20
-34/-12
1234500

Rejects

/
-/-
-23/
01234
-34/12
34/-12

Well, not shorter, but maybe more useful. (Your original expression excludes leading zeroes but also any zero in the expression.)

I came up with:

((^|\s+)-?[1-9]\d*\/-?[1-9]\d*($|\s+)|(^|\s+)-?[1-9]\d*($|\s+))

This makes use of the special regex characters: ? (optional), * (zero or more), + (1 or more), /d (numerals), /s (whitespace), ^ (line start), $ (line end), and the construct (abc|efg) for alternation.

The (^|\s+) and ($|\s+) isolate the fraction with white space or line marks. The -? allows an optional minus sign, [1-9] excludes leading zeroes, and the \d* allows zero or more trailing digits. The division symbol \/ is escaped for safety.

If leading zeroes aren't an issue, use

((^|\s+)-?\d+\/-?\d+($|\s+)|(^|\s+)-?\d+($|\s+))

These versions allow negation in both the numerator and denominator.

Related