-4

There is a very helpful article on how to validate roman numerals How do you match only valid roman numerals with a regular expression?

Regex has always been my achilles heel in spite of all my efforts. How do I expand the regular expression provided to match normal integers as well? The provided regular expression is:

/^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/
Community
  • 1
  • 1
John Gathogo
  • 4,495
  • 3
  • 32
  • 48
  • 1
    Can you further explain what sorts of input should pass validation? Can an arabic numeral appear inside a roman numeral? If not, then @Wiktor 's comment should do the trick. – Tim Biegeleisen Aug 29 '16 at 07:28
  • @WiktorStribiżew: not quite a good duplicate. – Cerbrus Aug 29 '16 at 07:32
  • @TimBiegeleisen: I know where I say 'normal' integers may mean different things to different people... in my case I just meant 1, 2, 3,... – John Gathogo Aug 29 '16 at 07:35
  • @WiktorStribiżew: It doesn't show how the regex alternation works. – Cerbrus Aug 29 '16 at 07:37
  • 1
    @WiktorStribiżew: for you, maybe. But maybe not for the OP. – Cerbrus Aug 29 '16 at 07:38
  • @WiktorStribiżew: Respectly, I beg to differ. Based on the answer given, `(new RegExp('^\d+$/')).test('XI');` will return false – John Gathogo Aug 29 '16 at 07:38
  • 1
    @JohnGathogo: It's fine for that example (although have an extra `/` in it), but in general, don't use `new RegExp` when dealing with a constant expression. Use `/.../` notation, so you don't have to worry about two layers of backslashes. (Also, not quite sure what you're saying there, Wiktor didn't suggest `/^\d+$/`.) – T.J. Crowder Aug 29 '16 at 07:39
  • @Crowder: Thanks for the advice. Wiktor did say its a perfect dupe. If it was, I'd think the answer given there would be a fit for this case. I was just trying to demonstrate that its not. – John Gathogo Aug 29 '16 at 07:45
  • Actually, I missed that it has `\d` in a string, so the ``\`` will be completely ignored. – T.J. Crowder Aug 29 '16 at 07:45
  • @JohnGathogo: Ah, sorry, I hadn't followed the conversation. – T.J. Crowder Aug 29 '16 at 07:46

1 Answers1

4

Assuming that you just want decimal integers in regular form (e.g., 1000 would be valid, 1e3 [the same number in scientific notation] would not), the regular expression to validate that is \d+, which means "one or more digit(s)."

To have your regular expression allow that, you'd want an alternation, which lets either of two alternatives match. Alternations are in the form first|second where first and second are the alternatives.

Since your current expression has "beginning" and "end" of input assertions (^ and $), we'd either want to include those in the second alternative as well, or put the entire alternation in a non-capturing group.

So either:

    /^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$|^\d+$/
// Note -----------------------------------------------------^^^^^^

(on regex101)

or

    /^(?:M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})|\d+)$/
//    ^^^                                                      ^^^^^

(on regex101)

Note that your original expression has a few capture groups (but doesn't entirely consist of captures); if you wanted to capture the \d+ part, you'd put () around it.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • @Crowder: I know integers may mean different things to different people... in my case I just meant 1, 2, 3,... – John Gathogo Aug 29 '16 at 07:41
  • @JohnGathogo: Just framing the problem in order to solve it. Sometimes people want to handle scientific notation as well, which complicates things a bit. – T.J. Crowder Aug 29 '16 at 07:43
  • @Crowder: I understand. My challenge has always been in combining two or more regex expressions in such a way that the combined expression has the expected outcome. That is what I never seem to master. – John Gathogo Aug 29 '16 at 07:58