14

If I have a magic Vim regex in a string literal, is there a way to convert the whole regex into an alternative representation that uses a different magic mode, so I could paste that equivalent regex into source code?

For instance, if I want to convert this magic-mode pattern:

'\m-\=\<\d\+L\=\>\|0[xX][0-9a-fA-F]\+\>'

to very-magic-mode to make it more readable, something like:

'\v-=<\d+L=>|0[xX][0-9a-fA-F]+>'

I often make mistakes trying to convert them by hand.

  • I'm not aware of one. Do you plan to always have them in single quoted strings? – FDinoff Oct 2 '16 at 3:10
  • Maybe this could be a starting point. I have however it only barely tested. – Christian Brabandt Oct 5 '16 at 17:45
  • concerning the question title, it is hard, think about converting a very magic regex [0-9]+ into a no magic one... ;-) – Kent Oct 12 '16 at 14:38
  • So I've been trying to make a plugin for that, it kind of work but it is far from being perfect. Also for the reference there is a plugin which converts ruby/perl regex to Vim regex, the code is... huge: eregex – statox Oct 13 '16 at 8:03
  • 1
    @MuMind I think I don't understand which type of comparison you're looking for :-) And about the improvement of the plugin, don't hesitate to test it an use github to signal a bug or even suggest a pull request, I'll gladly look a it! – statox Oct 14 '16 at 8:17
3

The command

:s\v\\(\W)/\1/

should suffice to transform most any pattern into \v mode. It won't swap out the lil' \m marker though - and to my knowledge that's impossible in a single replacement. It's short enough to type manually though, and then you can just do :s/\\m/\\v for the mode marker.

\W is shorthand for [^a-zA-Z0-9_] which is the (negated) set of characters that very magic mode operates on. This just deletes any backslashes immediately preceding one of those characters. Known issue: This will replace \\ inside strings to \. You could replace \W with \c[^a-z0-9\_] to mitigate this, but it'll still mess up your regex literal if you run it multiple times and also fail on longer escape strings (containing \\\\ for example)

Update: The original question makes it unclear if you need to transform \v back to \m, but the command there is:

:s/\v(\\)@<!(\c[^a-z0-9\-\\\[\]\'_])/\\\2/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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