2

I am pretty bad at regex and need some help implementing my idea with the already complicated if-else syntax being used for user-defined snippets in VS Code.

I want to achieve the following:

  • Whenever I enter a number for variable $1 I want the snippet to create the text "MAXVALUE $1" at the placeholder positon
  • if anything else is entered, there should be printed nothing

My current line for this with $1 being the variable I enter is:

"\t ${1/([0-9])|([a-zA-Z])/${1:+MAXVALUE }${2:+ }/}"

At this state I can capture the entire number EXCEPT the FRIST CHARACTER being entered and I can print MAXVALUE _mynumber_minus_char_at_index_0, LOL?!

If I enter a text, MAXVALUE won't be printed, but again the value from $1 minus the character at index 0 is being printed on screen.

Any help would be highly appreciated. If you got some useful links that explain advanced snippet creation for those kinda cases, I would be thankful as well.

For RegEx, well, time to learn them, so why not starting with a crazy-ass example like this - at least for me it is like rocket-science atm :D

Thanks in advance and best regards.

4
  • You probably just need + - "\t ${1/([0-9]+)|([a-zA-Z]+)/${1:+MAXVALUE }${2:+ }/}" Commented Apr 26, 2022 at 18:35
  • Unfortunately this does not have the desired effect. The "+" alone kills any input and when I try to escape it with "\+", I get the same result as described in my question - first character gone again. Thanks for your rapid reply. Commented Apr 26, 2022 at 18:58
  • "\t ${1/([0-9]+)|([a-zA-Z]+)/${1:+MAXVALUE }$1${2:+ }/}" I think that does what you want. If so I can explain it and what is wrong with your version. Do you want to see a gif of it working? Commented Apr 26, 2022 at 20:13
  • Amazing!But first of all: THANK YOU VERY MUCH! :) My eyes and ears are wide open to the explanation and what I did not understand correctly using this feature of VS Code :) Especially since I tried to change the variable name to e.g. $5 and it does not work anymore, when replacing ${1 resp. $1 with this value, it makes me curious what's behind the syntax as well :) Commented Apr 26, 2022 at 20:30

1 Answer 1

2

Using this snippet:

"Maxvalue": {
    "prefix": "cll",
    "body": [
      "\t ${1/([0-9]+)|([a-zA-Z]+)/${1:+MAXVALUE }$1${2:+ }/}",
    ],
    "description": "maxvalue"
},

snippet with conditionals

([0-9]+) captures all the numbers you type; or
([a-zA-Z]+) captures all the letters you type

You were using ([0-9]) which captures, but more importantly matches only the first number. If you don't match something it will not be transformed by the snippet transform, it just remains untouched. That is why you were seeing everything but the first number in the output.

You weren't actually outputting $1 anywhere - you see I added it to the transform after the MAXVALUE conditional.

${1:+MAXVALUE } is a conditional which means if there is a capture group 1, do something, in this case output MAXVALUE. That 1 in ${1:+MAXVALUE } is not a reference to your $1 tabstop. It is only a reference to the first capture group of your regex.

So you correctly outputted MAXVALUE when you had a capture group 1, but you didn't follow that up by outputting capture group 1 anywhere.

{2:+ } is anther conditional where the 2 refers to a capture group 2, if any, here ([a-zA-Z]+). So if there is a capture group 2, a space will be output. If there is no capture group 2, the conditional will fail and provide no output of its own. If you want nothing printed if you type letters, then match it and do nothing with it. As in the following:

"\t ${1/([0-9]+)|[a-zA-Z]+/${1:+MAXVALUE }$1/}", this will match all the letters you type (before tabbing to complete the transform) and they will disappear because you matched them and then didn't output them in the transform part anywhere.

If you simply want those letters to remain, don't match them as in

"\t ${1/([0-9]+)/${1:+MAXVALUE }$1/}"

If there is something you don't understand let me know.

[By the way, your question title mentions if/else conditions but you are using only if conditionals.]

Sign up to request clarification or add additional context in comments.

11 Comments

Awesome. That's a great explanation! :) But I have two questions in this regard: 1. How do you refer to the variable for the if-condition? I kinda don't understand why, when $1 is my variable, "\t ${1/([0-9]+)|([a-zA-Z]+)/${1:+MAXVALUE }$1/}" works the way I want it. But when I try to refer to another variable, let's say $3 "\t ${3/([0-9]+)|([a-zA-Z]+)/${1:+MAXVALUE }$3/}" does not work anymore and only MAXVALUE is being printed when entering a number. EDIT: Corrected my typo with $5 instead of $3
Second question: I tried to do a if-else clause and this kinda magically works printing both elements: "\t ${6/(y|1|true)|(n|false|[a-zA-Z0-9])/${1:+condi_1}${2:+condi_2 }/} " What did I do wrong in the first example when working with variable $5?
First question: Not sure I understand but any references like $3, $2, $n in the transform "body" - the replacement part like /${1:+MAXVALUE }$3/ are only references to a capture group in the preceding regex part - you cannot refer to a tabstop there - lots of people get confused by that. If there is no capture group 3 then $3 in a transform is basically an empty string and so outputs nothing.
Second question: variable $5 - I don't see a $5 anywhere.
"\t ${2/([0-9]+)|([a-zA-Z]+)/${1:+MINVALUE }$1/}" in the body which is an array, under the MAXVALUE line. Each line in the body is on a newline. $2 is your second tabstop. Tabstops, which I think you keep referring to as variables, can only be numbers like $4, etc.
|

Your Answer

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