Is there any implementation of regex that allow to replace group in regex with lowercase version of it?
6 Answers
If your regex version supports it, you can use \L, like so in a POSIX shell:
sed -r 's/(^.*)/\L\1/'

- 1,412
- 1
- 11
- 10
-
3This appears to work in a surprising number of regex kits, even if you're not in a shell-like environment. – Tim Jun 26 '13 at 22:28
-
3@Tim: Agreed, even Notepad++ supports it. – Nelson Rothermel Aug 15 '13 at 18:21
-
2This does not work in `zsh` or `bash` on OSX (yes I'm using `-E` instead of `-r`). – dcow Dec 21 '14 at 19:13
-
BSD sed is too limited. On OS X use Homebrew and install gnu-sed instead. Then it works. – Kim Dec 22 '14 at 09:19
-
1Works in Linux's `rename` command, which at least in Ubuntu 14 is a perl script (/usr/bin/prename). – Camille Goudeseune Jun 15 '15 at 15:45
-
Since `*` is greedy and `.` stands for any character, you don't have to anchor the pattern with `^`. With gnu sed, you can also remove the capture group and the -r switch and write: `sed 's/.*/\L&/'`. On the other hand writing `sed --posix 's/\(.*\)/\L\1/'` doesn't work with gnu sed (and add a L at the start of the line). – Casimir et Hippolyte Oct 28 '17 at 19:01
-
Just want to add that the \L works in VS Code as well. My replace regex is `$1\L$2` which keeps group 1 as it is, but change group 2 to lowercase. – ABVincita Mar 29 '22 at 06:02
In Perl, you can do:
$string =~ s/(some_regex)/lc($1)/ge;
The /e
option causes the replacement expression to be interpreted as Perl code to be evaluated, whose return value is used as the final replacement value. lc($x)
returns the lowercased version of $x
. (Not sure but I assume lc()
will handle international characters correctly in recent Perl versions.)
/g
means match globally. Omit the g
if you only want a single replacement.

- 50,331
- 10
- 105
- 169
-
2Perl also supports `\L` syntax, e.g. `s/(some_regex)/\L$1/g`, tested on 5.26. – Ciro Santilli OurBigBook.com Apr 25 '19 at 07:34
If you're using an editor like SublimeText or TextMate1, there's a good chance you may use
\L$1
as your replacement, where $1
refers to something from the regular expression that you put parentheses around. For example2, here's something I used to downcase field names in some SQL, getting everything to the right of the 'as' at the end of any given line. First the "find" regular expression:
(as|AS) ([A-Za-z_]+)\s*,$
and then the replacement expression:
$1 '\L$2',
If you use Vim (or presumably gvim), then you'll want to use \L\1
instead of \L$1
, but there's another wrinkle that you'll need to be aware of: Vim reverses the syntax between literal parenthesis characters and escaped parenthesis characters. So to designate a part of the regular expression to be included in the replacement ("captured"), you'll use \(
at the beginning and \)
at the end. Think of \
as—instead of escaping a special character to make it a literal—marking the beginning of a special character (as with \s
, \w
, \b
and so forth). So it may seem odd if you're not used to it, but it is actually perfectly logical if you think of it in the Vim way.
1 I've tested this in both TextMate and SublimeText and it works as-is, but some editors use
\1
instead of $1
. Try both and see which your editor uses.
2 I just pulled this regex out of my history. I always tweak regexen while using them, and I can't promise this the final version, so I'm not suggesting it's fit for the purpose described, and especially not with SQL formatted differently from the SQL I was working on, just that it's a specific example of downcasing in regular expressions. YMMV. UAYOR.

- 21,213
- 15
- 102
- 138
Several answers have noted the use of \L
. However, \E
is also worth knowing about if you use \L
.
\L
converts everything up to the next\U
or\E
to lowercase. ...\E
turns off case conversion.(Source: https://www.regular-expressions.info/replacecase.html )
So, suppose you wanted to use rename
to lowercase part of some file names like this:
artist_-_album_-_Song_Title_to_be_Lowercased_-_MultiCaseHash.m4a
artist_-_album_-_Another_Song_Title_to_be_Lowercased_-_MultiCaseHash.m4a
you could do something like:
rename -v 's/^(.*_-_)(.*)(_-_.*.m4a)/$1\L$2\E$3/g' *
In Perl, there's
$string =~ tr/[A-Z]/[a-z]/;

- 70,339
- 36
- 160
- 222
-
The [A-Z]? It was an example. That said, I voted for j_random_hacker's answer. – Hank Gay Jan 09 '09 at 11:10
Most Regex implementations allow you to pass a callback function when doing a replace, hence you can simply return a lowercase version of the match from the callback.

- 187,081
- 35
- 232
- 306