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.

Martin Tournoij
  • 62,054
  • 25
  • 192
  • 271
Mu Mind
  • 485
  • 3
  • 10
  • I'm not aware of one. Do you plan to always have them in single quoted strings? – FDinoff Oct 02 '16 at 03:10
  • Maybe this could be a starting point. I have however it only barely tested. – Christian Brabandt Oct 05 '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 08:03
  • I'm getting that overall there's no simple/complete solution but there are some patterns that can help for some cases. I wonder if vim's code could be modified into a tool to check patterns for equality based on some internal representation after parsing it or something. – Mu Mind Oct 13 '16 at 13:59
  • @statox Nice. https://github.com/tpope/vim-scriptease would be a good home for a utility like that. – Mu Mind Oct 13 '16 at 14:23
  • @MuMind: I'm not a regex theory expert but I think that testing patterns equality is a really hard task and more importantly it is not really the role of a text editor, maybe it would be better to have an external tool to do that? Also my little plugin is still really buggy I don't think it would really have the same quality as the tools developed by a vimguru like Tim Pope :) – statox Oct 13 '16 at 14:28
  • @statox I just mean symbol-for-symbol equality if it's handy inside the vim internal representations, and yeah I meant an external tool. – Mu Mind Oct 13 '16 at 20:28
  • @statox A good implementation in scriptease would still be nice, and yours is a start that could be improved in code review. All software is buggy when it's first written. – Mu Mind Oct 13 '16 at 20:31
  • 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 08:17
  • @statox I just meant that \v(a|b) and \m\(a\|b\) are trivially the same, there's a 1-to-1 translation between those forms, and there may be an easy way to equality check those if there's not a good way to convert between them automatically. It's a tangent, though, I pbb shouldn't have brought it up. – Mu Mind Oct 14 '16 at 17:36

2 Answers2

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/
Wolfie
  • 667
  • 3
  • 8
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

Good Pen
  • 211
  • 2
  • 5