You can capture a regex pattern using grouping and use that group to search further or replace it by appending or prepending text to it.
In the above screenshot, you can see that “Regex” is referred to as \1
and “Backreference” is referred to as \g{test}
.
Search and replace using backreference
vim
You can use &
to get hold of the previous matched word and replace text based on that text in vim.
For example if a file has below text
test | test | test | test | test | test
By using below command
:%s/test/"&"/g
contents get changed like below
"test" | "test" | "test" | "test" | "test" | "test"
With the above, we are confined to the last matched word. How about capturing multiple groups. For example, you have the below text in the file with username and id.
Tom u123
Mia u124
Zoe u125
Foo u126
By using below command
:%s/\(^.*\) \(.*$\)/select * from user where id="\2" and name="\1";/g
Will give below result
select * from user where id="u123" and name="Tom";
select * from user where id="u124" and name="Mia";
select * from user where id="u125" and name="Zoe";
select * from user where id="u126" and name="Foo";
Explanation -
\(^.*\)
- captured name
and grouped as 1
\(.*$\)
- captured rest of the word till end of line and grouped as 2
We are using \1
& \2
groups to get the captured text for replacing.
sed
You can also sed
in place substitute to do above without opening vim.
(base) ➜ more /tmp/test.txt
Tom u123
Mia u124
Zoe u125
Foo u126
(base) ➜ sed -i "" 's/\(^.*\) \(.*$\)/select * from user where id="\2" and name="\1";/g' /tmp/test.txt
(base) ➜ more /tmp/test.txt
select * from user where id="u123" and name="Tom";
select * from user where id="u124" and name="Mia";
select * from user where id="u125" and name="Zoe";
select * from user where id="u126" and name="Foo";
Note: sed in MacOS, requires -i ""
to skip creating backup file.
In Linux, you can skip empty quotes - ""
Python
In python, re
package can be used to accomplish the above task.
Capturing group
You can use (...)
to capture and use numbers starting from 1 to refer groupings.
import re
x = "Tom u123"
pattern = re.compile('([^ ]+) (.*)')
y = pattern.sub(r'select * from user where id="\2" and name="\1"', x)
print(y)
Will output below
'select * from user where id="u123" and name="Tom"'
Named Capturing group
You can use named grouping (?P<name>...)
to name groups instead of referencing using numbers.
import re
x = "Tom u123"
pattern = re.compile('(?P<first>[^ ]+) (?P<second>.*)')
y = pattern.sub(r'select * from user where id="\g<second>" and name="\g<first>"', x)
print(y)
will output below
select * from user where id="u123" and name="Tom"
Proxy servers
Regex Backreference is mainly used in proxy server configurations like Nginx and Apache.
For example, in Apache, regex backreference is used for the proxy pass.
ProxyPassMatch "^/(cart|club|api)/(.*)$" http://ui-server.qa.test.com/$1/$2
ProxyPassReverse "^/(cart|club|api)/(.*)$" http://ui-server.qa.test.com/$1/$2
Conclusion
Above are a few examples where you can use regex backreference to search and replace. There are many regex playgrounds like regexr.com, where you verify your regular expressions. All programming languages primarily support regex; check respective documentation to know the correct syntax for grouping and backreferencing. – RC
Comments