It's possible to do this with one substitution command but it's a bit hairy and you might want to just use two substitutions. For instance here's a two substitution version that has a bit of a shortcut in it...
:s/\(user\)s\?/\1_items/gI | s/\(USER\)S\?/\U~/g
The ~
in the replacement part of the second command copies the replacement of the last executed substitution (in our case from the LHS of the |
). By prepending that with \U
we force \1_items
to uppercase.
If you want to know the single substitution version...better take a seat. ;)
:s/\(user\)s\?/\=submatch(1) . (submatch(1) ==# 'user' ? '_items' : '_ITEMS')/gi
This is using what's known as a sub-replace expression. I've answered a couple question recently using this technique: How to run a substitute command on only a certain part of the line and How to create regex group with dependency with earlier group via math operations
The key is the \=
that begins the substitution. It means "everything after this point is to be evaluated as a VimL expression and the result of that evaluation becomes the replacement string". submatch(1)
is equivalent to \1
and we're appending to that a string that is conditional on the value of submatch(1)
. Specifically, the part between the parens says, If the submatch is case sensitively equal to 'user' then append to the submatch "_items" otherwise append "_ITEMS".
"
The two-substitution version is easier to understand and less typing so that's what I would use. If you really want to avoid typing a pattern more than once then, hmmm, you could use this, I suppose...
:let c='s/\(USER\)S\?/\1_ITEMS/I' | exe c | exe tolower(c).'I'
Alternatively, run the first substitution then run a second command...
:s/\(USER\)S\?/\1_ITEMS/I
:exe tolower(@:).'I'
Both of these do two substitutions but at least you only have to type one of them. ;)
(Just in case there's confusion, I don't actually recommend using either of the last two...they're a bit too hacky. But, hey, if you want to do so anyways then go for it. :)