Stack Exchange
Replace all occurrences of ' 1 ' with matched text in one line
I've got a text file, containing following lines
<a href="tg://proxy?server=radan.rooznameh.etellaate.rooz.romatism.sbs&port=443&secret=ee32b920dffb51643028e2f6b878d4eac175706c6f6164626f792e636f6d&bot=@mtpro_xyz_bot#ES">1<p> </a>
<a href="tg://proxy?server=digkala-com-heneri-com.1400.melbourne&port=443&secret=ee000000000000000000000000000000006b65746161626f6e6c696e652e636f6d&bot=@mtpro_xyz_bot#IE">2<p> </a>
<a href="tg://proxy?server=103.105.48.76&port=443&secret=eefacacf88a07e73d961d7029c1da7e64b64756f6c696e676f2e636f6d&bot=@mtpro_xyz_bot#GB">3<p> </a>
...
<a href="tg://proxy?server=5.28.193.20&port=443&secret=eed41d8cd98f00b204e9800998ecf8322e7777772e676f6f676c652e636f6d&bot=@mtpro_xyz_bot#DE">1315<p> </a>


I want to replace all ...>1<p>, ...>2<p>, ... near line ends with server addresses.
The text above should become
<a href="tg://proxy?server=radan.rooznameh.etellaate.rooz.romatism.sbs&port=443&secret=ee32b920dffb51643028e2f6b878d4eac175706c6f6164626f792e636f6d&bot=@mtpro_xyz_bot#ES">radan.rooznameh.etellaate.rooz.romatism.sbs<p> </a>
<a href="tg://proxy?server=digkala-com-heneri-com.1400.melbourne&port=443&secret=ee000000000000000000000000000000006b65746161626f6e6c696e652e636f6d&bot=@mtpro_xyz_bot#IE">digkala-com-heneri-com.1400.melbourne<p> </a>
<a href="tg://proxy?server=103.105.48.76&port=443&secret=eefacacf88a07e73d961d7029c1da7e64b64756f6c696e676f2e636f6d&bot=@mtpro_xyz_bot#GB">103.105.48.76<p> </a>
...
<a href="tg://proxy?server=5.28.193.20&port=443&secret=eed41d8cd98f00b204e9800998ecf8322e7777772e676f6f676c652e636f6d&bot=@mtpro_xyz_bot#DE">5.28.193.20<p> </a>

Please, scroll right to see the difference.
In other words, being opened in a browser, this file is rendered as a list of numbers, each of which is a link to the Telegram proxy. I want to replace these numbers with server addresses to make it look more pleasant.
I guess, g command can do the job, however, I don't know how to access matched group or matched pattern.
I've tried many variants, and the best is
:g/server=\(.*\)&/y a|s#>\[0-9\]\+<#\=getreg('a')#
It does not work, because y a command yanks the whole line while I need only part of it. And numbers in subsequent s command are not matched.
Is there any way to do it from the : line, without writing additional functions?
I understand that this task can be easily done with awk + sed, however, I think this is not sportive :)

Sounds like a sed, grep awk piping problem. Maybe you should ask here: https://unix.stackexchange.com/

That's not sportive :)

maybe :%!sed ...       :)

Unrelated, but why is there a <p> tag without closing </p> within the <a></a>? This does not look like clean HTML.

@Friedrich, the goal is to quickly find working proxy. I open this file in a browser, then each time I click on lines, browser opens Telegram, and I can check if it works.

Asking for external help is not sportive.

@wl2776 you could achieve the same with well-formed HTML. Well, whatever floats your raft.

You seem to be confused about :help :global.
The point of :g/<pattern>/<command> is to execute <command> on the lines that match <pattern>, not on the matches themselves.
This means that, in this case, :global is largely unnecessary if you want to use a substitution.
Let's simplify your sample a bit:
<a href="tg://proxy?server=r.r.e.r.r.sbs&p=443&s=c0ffee&b=@mtpro_xyz_bot#ES">1<p> </a>
<a href="tg://proxy?server=d-c-h-c.1.melbourne&p=443&s=c0ffe&b=@mtpro_xyz_bot#IE">2<p> </a>
<a href="tg://proxy?server=103.105.48.76&p=443&s=c0ffee&b=@mtpro_xyz_bot#GB">3<p> </a>

What you want to do can be done with a single substitution:
:%s/\(^.*server=\)\(.\{-}\)\(&.\{-}>\)\d\{-}/\1\2\3\2

The idea is to slice the line into capture groups during the search phase, and reconstruct the line how we want it in the replace phase.
First the slicing:
<a href="tg://proxy?server=r.r.e.r.r.sbs&p=443&s=c0ffee&b=@mtpro_xyz_bot#ES">1<p> </a>
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAA
                           BBBBBBBBBBBBB
                                                                             C

where A is the part we want to keep as-is, B is the part we want to reuse elsewhere, and C is the part we want to replace with B. What comes after C is irrelevant so we can concentrate on what comes before:
"pattern
\(^.*server=\)\(.\{-}\)\(&.\{-}>\)
+------------+                     group #1
              +-------+            group #2
                       +---------+ group #3

" sample
<a href="tg://proxy?server=r.r.e.r.r.sbs&p=443&s=c0ffee&b=@mtpro_xyz_bot#ES">1<p> </a>
+-------------------------+                                                   group #1
                           +-----------+                                      group #2
                                        +-----------------------------------+ group #3

Now that we have everything that comes before C split in three capture groups, we can reconstruct that part easily:
" replacement
\1\2\3

" result
<a href="tg://proxy?server=r.r.e.r.r.sbs&p=443&s=c0ffee&b=@mtpro_xyz_bot#ES"><p> </a>

and follow up with group #2, which contains the server name:
" replacement
\1\2\3\2

" result
<a href="tg://proxy?server=r.r.e.r.r.sbs&p=443&s=c0ffee&b=@mtpro_xyz_bot#ES">r.r.e.r.r.sbs<p> </a>

There is nothing hard to remember, here:

\(...\) creates a capture group,
\2 uses capture group #2.


Thank you for nice explanation. What is {-}? Never seen this before

It's a quantifier, meaning "zero or more of the preceding atom, as few as possible". See :help \{-.

I would do:
%s/proxy?server=\zs\([^&]*\)\(&.*\)\d\ze<p>/\1\2\1/

Here is an explanation:

proxy?server=\zs catch the url but ignore the first part for the replacement (\zs)
\([^&]*\)catch the server name and store it into \1
\(&.*\)\d\ze<p> catch the rest into \2 but exclude <p> from the replacement
\1\2\1 do the replacement you want.


If sed can do, it :substitute can do it as well (well, mostly).
Using this command: :s/server=\([^&]*\).*>\zs\d\+\ze<p>/\1/
Will convert each of these lines:
<a href="tg://proxy?server=radan.rooznameh.etellaate.rooz.romatism.sbs&port=443&secret=ee32b920dffb51643028e2f6b878d4eac175706c6f6164626f792e636f6d&bot=@mtpro_xyz_bot#ES">1<p> </a>
<a href="tg://proxy?server=digkala-com-heneri-com.1400.melbourne&port=443&secret=ee000000000000000000000000000000006b65746161626f6e6c696e652e636f6d&bot=@mtpro_xyz_bot#IE">2<p> </a>
<a href="tg://proxy?server=103.105.48.76&port=443&secret=eefacacf88a07e73d961d7029c1da7e64b64756f6c696e676f2e636f6d&bot=@mtpro_xyz_bot#GB">3<p> </a>
...
<a href="tg://proxy?server=5.28.193.20&port=443&secret=eed41d8cd98f00b204e9800998ecf8322e7777772e676f6f676c652e636f6d&bot=@mtpro_xyz_bot#DE">1315<p> </a>

into these:
<a href="tg://proxy?server=radan.rooznameh.etellaate.rooz.romatism.sbs&port=443&secret=ee32b920dffb51643028e2f6b878d4eac175706c6f6164626f792e636f6d&bot=@mtpro_xyz_bot#ES">radan.rooznameh.etellaate.rooz.romatism.sbs<p> </a>
<a href="tg://proxy?server=digkala-com-heneri-com.1400.melbourne&port=443&secret=ee000000000000000000000000000000006b65746161626f6e6c696e652e636f6d&bot=@mtpro_xyz_bot#IE">digkala-com-heneri-com.1400.melbourne<p> </a>
<a href="tg://proxy?server=103.105.48.76&port=443&secret=eefacacf88a07e73d961d7029c1da7e64b64756f6c696e676f2e636f6d&bot=@mtpro_xyz_bot#GB">103.105.48.76<p> </a>
...
<a href="tg://proxy?server=5.28.193.20&port=443&secret=eed41d8cd98f00b204e9800998ecf8322e7777772e676f6f676c652e636f6d&bot=@mtpro_xyz_bot#DE">5.28.193.20<p> </a>

Note that this runs on a single line only; use :%s... to run on the whole buffer.
