Using named matching groups is often easier to understand than numbering groups but takes up more bytes. Given a regular expression as specified below, your program or function must convert named groups to numbered groups.
Task
These specifications are based on python 3's re module.
A named group takes the form of (?P<name>...)
where name
is replaced with the name of the group and ...
is a valid regex.
A reference to a named group takes the form of (?P=name)
where name
is replaced with the name of the group.
A numbered group takes the form of (...)
where ...
is a valid regex.
A reference to a numbered group takes the form of \number
where number
is replaced with the number of the group as follows:
groups are numbered from left to right, from 1 upward. Groups can be nested; to determine the number, just count the opening parenthesis characters, going from left to right. (Python howto)
The number of opening parentheses characters includes the group's opening parenthesis.
Thus your program or function must, given a valid regular expression, convert named groups to numbered groups and references to named groups to references to numbered groups with the right number.
Example
The input is s(tar)+t(?P<name1>subre)cd(?P=name1)
. The (?P=name1)
bit refers to the capturing group (?P<name1>subre)
. It is group 2
because the string s(tar)+t(
contains two opening parentheses. Thus (?P=name1)
is replaced with \2
to get s(tar)+t(?P<name1>subre)cd\2
The (?P<name1>subre)
group can be converted to a non-named group by simply removing the name and identification to get (subre)
. Applying this into the string so far yields s(tar)+t(subre)cd\2
. Since there are no named groups nor named references, the program is done and outputs s(tar)+t(subre)cd\2
.
Rules
- There are no non-capturing groups in the input regular expression (in other words, all groups are either numbered or named).
- You may assume that all input groups are named.
- Any further pedantics due to technical specifications of regular expressions should be ignored.
- The input will always contain no digits directly after named backreferences.
- Every reference to a named group in the input will have an actual named group to reference to.
- All parentheses in the input delimit a group
- The group names will contain no spaces.
The output may optionally have a trailing newline.
Brownie points for solving this challenge using a regular expression!
Remember Defaults:
- This is code-golf, so shortest code in each language wins.
- Of course, standard loopholes are forbidden.
- The input and output should be taken in standard I/O methods.
Test Cases
Input
Output
-----
this has no* groups \bubbles
this has no* groups \bubbles
-----
this has (?P<name>named)+ groups (?P=name)
this has (named)+ groups \1
-----
this has no(?P<references> sadness*)?
this has no( sadness*)?
-----
I need (?P<reference> very+ much) here is one: (?P=reference)
I need ( very+ much) here is one: \1
-----
t(?P<one>o)n(?P<another>s) of (?P<groups>named) groups (?P=another) (?P=one) (?P=groups)
t(o)n(s) of (named) groups \2 \1 \3
-----
Of course, we need (?P<moregroups>misdirection) (?P<n>n(?P<e>e(?P<s>s(?P<t>t)i)n)g) (?P=n)n(?P=e)e(?P=s)s(?P=t)ing
Of course, we need (misdirection) (n(e(s(t)i)n)g) \2n\3e\4s\5ing
-----
(?P<Lorem>Lorem ipsum dolor sit amet), (?P<consectetur>consectetur adipiscing elit), (?P<sed>sed do eiusmod tempor incididunt ut labore et dolore magna aliqua). (?P<Ut>Ut enim ad minim veniam, (?P<quis>quis) nostrud exercitation ullamco laboris nisi ut (?P<aliquip>aliquip ex ea commodo consequat.)) Duis aute irure dolor in (?P<finale>reprehenderit in voluptate velit esse cillum dolore eu fugiat (?P<null>null)a pariatur. (?P<Except>Excepteur (?P<sin>sin)t occae(?P<cat>cat) )cupidatat non proident, sunt) in culpa qui officia deserunt mollit anim id est laborum. (?P=cat)(?P=sin)(?P=Except)(?P=null)(?P=finale)(?P=aliquip)(?P=quis)(?P=Ut)(?P=sed)(?P=consectetur)(?P=Lorem)
(Lorem ipsum dolor sit amet), (consectetur adipiscing elit), (sed do eiusmod tempor incididunt ut labore et dolore magna aliqua). (Ut enim ad minim veniam, (quis) nostrud exercitation ullamco laboris nisi ut (aliquip ex ea commodo consequat.)) Duis aute irure dolor in (reprehenderit in voluptate velit esse cillum dolore eu fugiat (null)a pariatur. (Excepteur (sin)t occae(cat) )cupidatat non proident, sunt) in culpa qui officia deserunt mollit anim id est laborum. \11\10\9\8\7\6\5\4\3\2\1
(Above, I was referring to numbered groups as being disjoint from named groups, when named groups are also numbered. Pretend that I meant non-named groups when I said numbered groups.)
<>
s around backreference name). \$\endgroup\$