1

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.

Programmosaurus
  • 111
  • 1
  • 8
  • You probably just need `+` - `"\t ${1/([0-9]+)|([a-zA-Z]+)/${1:+MAXVALUE }${2:+ }/}"` – Wiktor Stribiżew Apr 26 '22 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. – Programmosaurus Apr 26 '22 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? – Mark Apr 26 '22 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 :) – Programmosaurus Apr 26 '22 at 20:30

1 Answers1

3

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.]

Mark
  • 143,421
  • 24
  • 428
  • 436
  • 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 – Programmosaurus Apr 26 '22 at 21:03
  • 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? – Programmosaurus Apr 26 '22 at 21:05
  • 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. – Mark Apr 26 '22 at 21:13
  • Second question: `variable $5` - I don't see a `$5` anywhere. – Mark Apr 26 '22 at 21:16
  • I have 6 variables in total and for some of them I want to do the conditional checking. One of them is the one from the example, that I wanted to changed from variable 1 to 5. The other one, variable number 6 is doing the if else part, which works without issues. – Programmosaurus Apr 26 '22 at 21:22
  • Since I kinda get confused with the numbers I have another question: Can I give those variables also alphanumeric names or do they have to have this sequence of numbers to work in the snippets? – Programmosaurus Apr 26 '22 at 21:26
  • For example, if $1 is my variable, "\t ${1/([0-9]+)|([a-zA-Z]+)/${1:+MAXVALUE }$1/}" and it works, what do I have to change to do exactly the same check for another variable? Which elements I have to replace to apply the regex checks on another value I entered during the snippet dialogue? What would I have to change to e.g. print MINVALUE for a other variable as well in another line? – Programmosaurus Apr 26 '22 at 21:29
  • 1
    `"\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. – Mark Apr 27 '22 at 02:14
  • Okay, after a night of sleep AND my screen magnifier on I could spot my bug THANK YOU very much for the insight on this topic and taking your time. You helped me a lot! I will play around and excercise with it a little bit more. Do you maybe have some sources, that you can recommend where to read more about the syntax for snippets and what kinda different constructs are possible to use? I mean,not just regEx-related, just generally speaking. – Programmosaurus Apr 27 '22 at 06:00
  • In this regard, I have one question,. when dealing with those conditionals: Let's say my string matches the numbers condition ([0-9]+). Is is possible that I can further process it? For example, when entering a number and 1-n other characters together, I want to remove anything not being number 1-4 from the element OR replacing 1-4 by some other character and eventually print the result. I'm thinking of some kinda further processing of tabstops. Or is this not possible? – Programmosaurus Apr 27 '22 at 06:18
  • I can realize my described example in the 3rd line, replacing "f" by "ZZ" in the entire text, but I would like to make this happen in the line above, so that my conditional pattern also matches: "/* ${1} /*" , "\t ${1/([0-9]+)|([a-zA-Z]+)/${1:+MAXVALUE } $1/}" "\t ${1/f/ZZ/g}" – Programmosaurus Apr 27 '22 at 06:22