18

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.

11
  • I'm not aware of one. Do you plan to always have them in single quoted strings?
    – FDinoff
    Commented Oct 2, 2016 at 3:10
  • Maybe this could be a starting point. I have however it only barely tested. Commented Oct 5, 2016 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
    Commented Oct 12, 2016 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
    Commented Oct 13, 2016 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
    Commented Oct 14, 2016 at 8:17

2 Answers 2

4

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/
0

based on @Wolfie's answer:

:subs #\v\\(\W)#\1#gc

to use # instead of / (I hate / and \ together):
:subs ^\/^#^gc

May need some manual check

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.