2

I've currently got the following code:

if ($str =~ m{^[A-Z]+-\d+$} || $str =~ m{^\d+$}){
    # do stuff
}

Is it possible to combine the 2 regular expressions into a single expression? And would that improve performance at all?

ewok
  • 17,202
  • 40
  • 122
  • 224
  • 1
    You may easily combine them using `^(?:[A-Z]+-)?\d+$` – Wiktor Stribiżew Jul 14 '17 at 20:43
  • 1
    yes use: `$str =~ m{^(?:[A-Z]+-)?\d+$}` – anubhava Jul 14 '17 at 20:43
  • 1
    What you ask, as answered by [Wiktor Stribiżew](https://stackoverflow.com/users/3832970/wiktor-stribi%C5%BCew), in the first place improves how the intent is conveyed -- match `\d+` optionally preceded by that other. It's just clearer that way, than when written with `||`. Which is faster depends on which case happens more often, but I'd say that _on average_ the single regex should be faster since it never starts the engine twice. – zdim Jul 14 '17 at 20:58
  • 1
    As a side note, there is an interesting post where [regex optimization in Perl](https://stackoverflow.com/questions/36420517/is-it-faster-to-use-alternation-than-subsequent-replacements-in-regular-expressi/36611087#36611087) is discussed. If the patterns could not be "joined" with an optional non-capuring group, I think it would be more appropriate to just use the `||` with two separate regexps as *"alternations hinder the optimizer"*. – Wiktor Stribiżew Jul 14 '17 at 21:14

1 Answers1

3

I would use an optional non-capturing group and combine these two into

if ($str =~ m{^(?:[A-Z]+-)?\d+$}) {
    # do stuff
}

Details

  • ^ - start of string
  • (?:[A-Z]+-)? - an optional non-capturing group (? quantifier makes it match 1 or 0 times)
  • \d+ - 1 or more digits
  • $ - end of string.
Wiktor Stribiżew
  • 484,719
  • 26
  • 302
  • 397