UPD guys, the above statement "This question already has an answer here: <link>" is just plain wrong: there is no answer there. I know about sed, but this is not an option. It looks like this is just not possible. Not in bash, not in a one-liner, not in 2018.
The bash string substitution supports regular expressions, but I cannot find a way to include a part of the matched string into the replacement.
The following does not do what I want:
$ x=AbcdAbdcAbefAbfe
$ echo ${x//Ab[ef]/Zy\\1}
AbcdAbdcZy\1fZy\1e
$ echo ${x//Ab[ef]/AB\1}
AbcdAbdcAB1fAB1e
(well, in fact, I cannot even use parens:
$ echo ${x//Ab/Zy}
ZycdZydcZyefZyfe
$ echo ${x//(Ab)/Zy}
AbcdAbdcAbefAbfe
)
What I want may be achieved via a series of substitutions:
$ x=AbcdAbdcAbefAbfe
$ t="$x"
$ t=${t//Abe/Zye}
$ t=${t//Abf/Zyf}
$ echo $t
AbcdAbdcZyefZyfe
but even for [0-9] it becomes a long story.
The code runs in a long loop, it should be a one-liner that does not launch sub-processes.
EDIT
There is an answer in the comments. I copy it here:
this was not a question about regular expressions, and that assumption in the question was incorrect. The initial sentence in the question posits something that is false. The pattern in a parameter expansion is treated as a glob. – ghoti
You should have probably linked to this directly. That page elaborates on everything needed to put an end to this discussion. – revo