Kimmax
Kimmax

Reputation: 1697

Remove duplication from regex

I'm using following regex, but as you can see there is much recursion in the expression.
Is there a better way to solve this?
What I need is kind of a "jump" operator.

((letzter|voriger|letztes|voriges) (lied|title|song))( (höhren|abspielen))?|((lied|title|song)( (wiederholen|erneut (höhren|abspielen))))

Regular expression visualization

Debuggex Demo

Upvotes: 1

Views: 54

Answers (1)

Mariano
Mariano

Reputation: 6511

PCRE implements subroutine calls, to achieve exactly what you need.

  • (?P<groupname>subpattern) defines a group.
  • \g<groupname> calls the group.

Regex:

/
(?:(?P<relative>letzte[rs]|vorige[rs])[ ])?        # optional non-capturing group
(?P<what>lied|title|song)
(?(relative)                                       # IF group <relative> was matched
    (?:[ ](?P<action>höhren|abspielen))?           # another optional non-capturing group
  |
    [ ](wiederholen|erneut[ ]\g<action>)           # subroutine call to group <action>
)
/ix

Regular expression visualization

Debuggex Demo


PCRE allows some ways to define a group, all of them with the same meaning:

  • (regex) Group
  • (?P<name>regex> Group named name.
  • (?'name'regex) Group named name.
  • (?<name>regex) Group named name.

as well as different ways to make subroutine call:

  • (?3) Recurse/call group 3.
  • \g<3> Recurse/call group 3.
  • \g'3' Recurse/call group 3.
  • (?-1) Recurse/call previous group.
  • \g<-1> Recurse/call previous group.
  • \g'-1' Recurse/call previous group.
  • \g<-1> Recurse/call previous group.
  • (?&name) Recurse/call group named name.
  • (?P>name) Recurse/call group named name.
  • \g<name> Recurse/call group named name.
  • \g'name' Recurse/call group named name.

Upvotes: 1

Related Questions