How to capitalize the second appearance of the same variable in WebStorm? - webstorm

I have the following WebStorm Live Template:
[$VAR1$, set$VAR1$]
My goal is to capitalize the second occurrence of $VAR1$.
e.g. for the input: foo
the output should be: [foo, setFoo]
right now the output is: [foo, setfoo]
For Live Templates, there is a Dialog where I can define a function expression to capitalize a variable:
The problem here is that the definition is per variable, so both occurrences are capitalized then.
How can I capitalize only the second occurrence, or copy the value of one variable into another one which would be capitalized then?

Just add another variable:
$VAR1$, set$VAR2$
See https://blog.jetbrains.com/webstorm/2022/02/creating-and-using-code-snippets-with-placeholders/, you may find this blog post useful

Related

Regex (flavor: PCRE) filter for matching first instance of character string THEN only filter in context of that first instance?

I want to match the first instance of "start" within this initial string
abcdstartabcdstartghijstartghij
I used the following regex to (not greedy) grab everything through the first "start."
^.*?start
Now, I filter for the FIRST instance of "start" with "ghij" attached to it.
When I tried the following, it filtered up to the SECOND "start" with "ghij"
^.*?startghij
My problem is I want it so that it CANNOT find "start" with "ghij" because "ghij" is NOT with the first "start". Basically I want that latter filter to fail.
What regex filter would filter for that first instance and only in context of that first instance? It should not go to the second "start" even though that has "ghij".
I hope my example explained my question a little more clearly.
There is no such thing as "on the n-th occurrence of ... also do ...", at least not directly. View the problem of the n-th occurence as "there were n - 1 occurrences before".
In your case you look for the first occurrence which means exactly no occurrences before.
So instead of the .*? part you need to match a string not containing a certain substring.
In your case this would become something like this:
^(?:(?!start).)*?startghij
This should work on most regex flavors as well.

Match Parent Folder in Sublime Text 3 Snippet

I'm trying to create a snippet that outputs a file's parent folder name. For example:
/Users/user/src/Page/index.js
returns
Page
I've got this regex pattern:
([^\/]+)(?:\/[^\/]+)$
Which, according to Regex101, matches Page/index.js with Page in group 1.
Trying this:
${1:${TM_FILEPATH/([^\/]+)(?:\/[^\/]+)$/$2/}}
returns
/Users/user/src/
Which makes me think I'm doing this entirely wrong.
I'm not sure how to use Sublime/Perl's string format options to actually return the proper string. I may not even have a correct pattern. What is the best way to do this?
I think you might be falling victim to the assumption that when you use a substitution to rewrite a field (or in this case variable) that the entire variable is replaced with the replacement text in the regular expression.
In fact what happens is that the regular expression is matched, the matched text in the variable is replaced with the replacement that you provide in the regex, and then the whole (newly modified) variable value is inserted.
For example, take the following snippet:
<snippet>
<content><![CDATA[
${TM_FILEPATH/./=/}
]]></content>
<tabTrigger>lpc</tabTrigger>
<description>Last path component of the current file</description>
</snippet>
That is "match any character, replace it with an equal sign". If you expand this snippet, the result is:
=home/tmartin/Test/sample.txt
The first slash matched and was replaced, and then the variable expands out as a weirdly broken path.
As such, in order to capture just the last path component, the regular expression that you use has to entirely consume the whole of the variable value, so that the replacement replaces the whole value with just the part you want.
A (probably ham-handed) example of that is this snippet:
<snippet>
<content><![CDATA[
${TM_FILEPATH/^.*\/([^\/]+)\/[^\/]+$/$1/}
]]></content>
<tabTrigger>lpc</tabTrigger>
<description>Last path component of the current file</description>
</snippet>
Now from the start of the string it greedily matches everything, followed by a slash, then a capture group that captures the last path segment, followed by one last slash and the remainder of the line right up to the end of the string.
The replacement in this case is more what you would expect:
Test

How to replace a sentence

How to replace the text
input:
This glass contains 1.5l of milk. But i don't like milk
ouptput:
Replace_text But i don't like milk
I need to replace text from the beginning to the next full dot. But i don't know what was the sentence.
vim has its definition of sentence. This you can read :h sentence.
For your example, I would do (assume your cursor is at the BOL):
c)WAHTEVER
The c) will remove the 1st sentence and enter INSERT mode.
To do batch replacement, you can record macro or make use of normal command.
What about this substitution command?
:%s/\(.\{1,}\)\.\(\w*\)/Replace_text\2/g
or using character classes (you might need to add special characters etc):
([\w\s]+\.\S[\w\s]+)\.(.*)
http://regexr.com/3cc0r
You can do the following
^cf.
It jumps to first non-blank character, deletes text including . and puts you in insert mode so that you can type in Repace_text.
If you want to change till the ., change f with t
You can also make use of text objects. cis will let you change the sentence.

In Vim, How to substitute within a subexpression?

I want to prepend all my classNames with o- without having to adjust every className by hand. I use Vim.
I know a substitution will do the job so I came up with this, which is obviously not working (and the reason I am here).
:%s/class="[^"]*"/\='class="'.substitute(submatch(0), '[^o-]*', 'o-'.submatch(1), 'g').'"'/g
Explanation:
class="[^"] - matches all instances of class="foo bar baz"
\='class="'.substitute(subexp).'"' - replaces the found instances class="subexp"
subexp in two should repace each space separated class with the original className prepended with o-
All in all, in procedural terms, for each class="foo bar baz", replace each className with the className prepended with o-.
Thanks in advance.
(BONUS) EDIT: How can this be written to ignore or cope with classNames that already begin with o-, when encountered, so that o-o- is not a resulting edit.
for the example
class="foo bar baz"
This line works:
%s/class="\zs[^"]*\ze"/\=join( map(split(submatch(0)),"'o-'.v:val"), ' ')/
So there are nested function calls:
I didn't use \< boundary because in case some "special" char in your classname, it will fail. E.g. # - or #. I don't know if it is the case in your language.
submatch(0) is the "foo bar baz"
split() makes it(each class) into list
map() add o- to each classname
join() turns the modified list back to string
So after executing this command, you should see:
class="o-foo o-bar o-baz"
Edit for the "Bonus" requirement:
We just need check each element(classname). Check the codes below, it should work for you:
%s/class="\zs[^"]*/\=join(map(split(submatch(0)),"(v:val=~'^o-'?'':'o-').v:val"))/
here we have:
(v:val=~'^o-'?'':'o-').v:val
If the element starts with o- then we don't add another o- any more.
One way to do it is to take advantage of \zs...\ze, and the fact that submatch(0) resolves to the string matched between \zs...\ze:
:%s/\mclass="\zs.\{-}\ze"/\=substitute(submatch(0), '\<', 'o-', 'g')/g
If you don't want to rely on that you can still use explicit grouping:
:%s/\mclass="\zs\([^"]*\)\ze"/\=substitute(submatch(1), '\<', 'o-', 'g')/g

Extract querystring value from url using regex

I need to pull a variable out of a URL or get an empty string if that variable is not present.
Pseudo code:
String foo = "http://abcdefg.hij.klmnop.com/a/b/c.file?foo=123&zoo=panda";
String bar = "http://abcdefg.hij.klmnop.com/a/b/c.file";
when I run my regex I want to get 123 in the first case and empty string in the second.
I'm trying this as my replace .*?foo=(.*?)&?.*
replacing this with $1 but that's not working when foo= isn't present.
I can't just do a match, it has to be a replace.
You can try this:
[^?]+(?:\?foo=([^&]+).*)?
If there are parameters and the first parameter is named "foo", its value will be captured in group #1. If there are no parameters the regex will still succeed, but I can't predict what will happen when you access the capturing group. Some possibilities:
it will contain an empty string
it will contain a null reference, which will be automatically converted to
an empty string
the word "null"
your app will throw an exception because group #1 didn't participate in the match.
This regex matches the sample strings you provided, but it won't work if there's a parameter list that doesn't include "foo", or if "foo" is not the first parameter. Those options can be accommodated too, assuming the capturing group thing works.
I think you need to do a match, then a regex. That way you can extract the value if it is present, and replace it with "" if it is not. Something like this:
if(foo.match("\\?foo=([^&]+)")){
String bar = foo.replace("\\?foo=([^&]+)", $1);
}else{
String bar = "";
}
I haven't tested the regex, so I don't know if it will work.
In perl you could use this:
s/[^?*]*\??(foo=)?([\d]*).*/$2/
This will get everything up to the ? to start, and then isolate the foo, grab the numbers in a group and let the rest fall where they may.
There's an important rule when using regular expressions : don't try to put unnecessary processing into it. Sometimes things can't be done only by using one regular expression. Sometimes it is more advisable to use the host programming language.
Marius' answer makes use of this rule : rather than finding a convoluted way of replacing-something-only-if-it-exists, it is better to use your programming language to check for the pattern's presence, and replace only if necessary.