2

If I'm using a range in a regex, how can I replace with the character that was matched? For example, lets say I want to find all occurrences of a or b, and replace them with aa or bb. Can I do this in a single regex? For example, something like this:

:%s/[a-b]/\1\1/g

Where \1 means the first matching character? Can I extend this to several characters? For example converting camelCase to snake_case. Can I do something like this:

%s/[a-z][A-Z]/\1_\2/g

Where \1 is the first matching character and \2 is the second matching character?

0

2 Answers 2

3

For using the entire matched text, just use &:

magic   nomagic   action    
  &       \&      replaced with the whole matched pattern            s/\&
 \&        &      replaced with &

So:

%s/[a-b]/&&/g

For using the matched text in parts, use regex groups:

\(\)    A pattern enclosed by escaped parentheses.      /\( /\(\) /\)
        E.g., "\(^a\)" matches 'a' at the start of a line.
        E51 E54 E55 E872 E873

\1      Matches the same string that was matched by     /\1 E65
        the first sub-expression in \( and \). {not in Vi}
        Example: "\([a-z]\).\1" matches "ata", "ehe", "tot", etc.
\2      Like "\1", but uses second sub-expression,      /\2
   ...                                                  /\3
\9      Like "\1", but uses ninth sub-expression.       /\9
        Note: The numbering of groups is done based on which "\(" comes first
        in the pattern (going left to right), NOT based on what is matched
        first.

So:

%s/\([a-z]\)\([A-Z]\)/\1_\2/g

Or more conveniently, enabling magic:

%s/\v([a-z])([A-Z])/\1_\2/g
3
  • Fantastic! That's exactly what I'm looking for. Thanks!
    – DJMcMayhem
    Commented Mar 24, 2016 at 17:18
  • 2
    May want to use \l to lowercase the next letter in the substitution. e.g. %s/\([a-z]\)\([A-Z]\)/\1_\l\2/g. See :h s/\l for more information. Commented Mar 24, 2016 at 17:46
  • @DJMcMayhem see Peter's suggestion, it should be useful for the camelcase conversion.
    – muru
    Commented Mar 24, 2016 at 17:48
2

You can easily change from camelCase style to snake_case style via the Abolish.vim plugin

%s/\<\l\+\u\w\+/\=Abolish.snakecase(submatch(0))/g

Abolish also provides "Coerce" mappings:

  • crc - coerce to camelCase
  • crs - coerce to snake_case
  • crm - coerce to MixCased
  • cru - coerce to UPPERCASE_SNAKE_CASE
  • cr- - coerce to dashed-case

There is Vimcasts eposide on use Abolish: Smart search with :Subvert

For more help see:

:h /\<
:h /\l
:h /\u
:h sub-replace-expression

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.