Regex to select and replace stuff, keeping patterns - regex

I want to change some strings:
space+cows --> space + cows
stupid+rabbit --> stupid + rabbit
(put spaces around the `+`)
In Sublime Text 2, I tried to use these:
Find: \w+\+\w+
Replace: \w+ \+ \w+
The finding regex matched everything well, but obviously, my strings were replaced with literally
w+ + w+.
One more example:
Strings:
bool *foo --> bool* foo
int *bar --> int* bar
Pattern:
Find: (bool|int) *(foo|bar)
Replace: (bool|int)* (foo|bar)
Result:
(bool|int)* (foo|bar)
(bool|int)* (foo|bar)
Needless to say I wanted to keep the actual bool, int, foo and bar as they were before.
I also cannot use only ­ \* to match the strings because it would select other stuff that I don't want to replace; I need some context around the actual ­ \* to select the correct strings. In the same way, I cannot use patterns like ­ \*[^ ­ ] because the not-space character after the asterisk would be obliterated after replacement.
I fixed my problem by using Sublime Text's multiline edition but I am still wondering: is it possible to use a regex in such a way that you can replace strings containing "group of characters" without wiping the actual contents of the "group of characters"?

Yes, this is possible. The reason your replacements don't work is (as you've noticed) your replacement text is just literal text; whatever you put in the box is what replaces what was matched as you would expext.
What you need to do is use a RegEx capture for this. What this does is make the regular expression processor (in this case Sublime Text) not only match the test but also store it for use in the replacement. You do that by wrapping the parts of the match you want to save in parenthesis. Each set of parenthesis is a Capture Group.
For your example, your regex becomes"
(\w+)\+(\w+)
The value of the match inside each set of parenthesis is saved into it's own numeric group, starting at one. A syntax like the following expands out to the contents of the first match, followed by the plus sign with spaces around it, followed by the second word:
\1 + \2
You can use each number multiple times, if you want:
\1 and again \1 and also \2

Regex to turn "stupid+rabbit" to "stupid + rabbit"
Find: (\w+)\+(\w+)
Replace: $1 + $2
Regex to turn "bool *foo" or "int *bar" into "bool* foo" or "int* bar"
Find: (bool|int) \*(foo|bar)
Replace: $1* $2
() - forms groups which can be later used. $1 is the first group and $2 is the second group.

Related

VSCode wildcard Search and Replace Regex

I'm trying to do a project wide search and replace
from:
drivers[i].findElement(By.id("elementID")).click();
to:
findAndClick(driver[i], "elementID", true)
The issue is the elementID can be anything so I'm trying to wildcard search and replace with what's in the wildcard?
You'll need to use .+? instead of * here since this uses regular expressions.
In regular expressions a dot . means "any character", the plus + means "one or more times", and the question mark ? after this means "try to match this as few as possible times" - which is useful so it won't keep matching past your quote marks
edit
To be clear though, you have to make a valid regex, which means you'll need to escape your parenthesis, dots, etc.
Here's the full solution
Find: drivers\[i\]\.findElement\(By\.id\("(.+?)"\)\)\.click\(\);
replace with: findAndClick(driver[i], "$1", true)
Note the added unescaped parentheses in there around the "wildcard" (.+) this creates a capture group in a regex, which is what translates to $1 in the replacement since it's the 1st capture group.

regex preserve whitespace in replace

Using REGEX (in PowerShell) I would like to find a pattern in a text file that is over two lines and replace it with new text and preserve the whitespace. Example text:
ObjectType=Page
ObjectID=70000
My match string is
RunObjectType=Page;\s+RunObjectID=70000
The result I want is
ObjectType=Page
ObjectID=88888
The problem is my replacement string
RunObjectType=Page;`n+RunObjectID=88888
returns
ObjectType=Page
ObjectID=88888
And I need it to keep the original spacing. To complicate matters the amount of spacing may change.
Suggestions?
Leverage a capturing group and a backreference to that group in the replacement pattern:
$s -replace 'RunObjectType=Page;(\s+)RunObjectID=70000', 'RunObjectType=Page;$1RunObjectID=88888'
See the regex demo
With the (\s+), you capture all the whitespaces into the Group 1 buffer and then, using $1 backreference, the value is inserted into the result.

Replace regular expression placeholder followed by number in Sublime Text 2

Let's say I want to add a 0 after every word
(\w+)
The following replacement string doesn't work.
$10
So, how do I convert
this is my string
into
this0 is0 my0 string0
Use braces around the group ID in the replacement string:
${1}0
The braces tell the regex engine that the number inside them is the actual Group ID. The 0 that will follow will be treated as a literal zero.
BTW, you can also get the same result with \w+ regex and ${0}0 replacement string, no need in capturing groups.
Or, using \n syntax, it works like this:
Find: (\w+)
Replace: \10

NOTEPAD++ REGEX - I can't get what's in between two strings, I don't get it

I'm so close to understanding regex. I'm a bit stumped, I thought i understood lazy and greedy.
Here is my current regex: <g_n><!\[CDATA\[([^]]+)(?=]]><\/g_n>)
My current regex makes:
<g_n><![CDATA[xxxxxxxxxx]]></g_n>
match to:
<g_n><![CDATA[xxxxxxxxxx
But I want to make it match like this:
xxxxxxxxxx
You want
<g_n><!\[CDATA\[(.*?)]]></g_n>
then if you want to replace it use
\1
in the replacement box
Your matching the whole string, the brackets around the .*? match all of that and put it in the \1 variable
So the match will be all of the string with \1 referring to what you want
To change the xxxxx
Regex :
(<g_n><![CDATA[)(?:.*?)(]]></g_n>)
Replacement
\1WHAT YOU WANT TO CHANGE TO\2
It looks like you need to add escape slashes to the two closing square brackets, as they are literals from the string you're parsing.
<g_n><!\[CDATA\[.*+?\]\]><\/g_n>
^ ^
Any square brackets not being escaped by backslashes will be treated as regex operational brackets, which in this case won't catch the input string.
EDIT, I think the +? is redundant.
\[.*\]\]> ...
should suffice, since .* means any character, any amount of times.
Tested with notepad++ 6.3.2:
find: (<g_n><!\[CDATA\[)([^]]+)(?=]]></g_n>)
replace: $1WhatYouWant
You can replace + by * in the pattern to match void CDATA:
<g_n><![CDATA[]]></g_n>

Regex Replace Whilst Retaining MetaInfo?

Although im using c# and the .net lib, im interested in a regex-only solution for some text replacement, and am a bit confused by the final hurdle. (Im using http://gskinner.com/RegExr)
Ive got the string
"Foo {0} Bar {1}"
I can use {[0-9]} to match, but when it comes to replacing, id like to keep the number, i.e. would produce:
"Foo $0$ Bar $1$"
If I had decided I wanted to replace curly braces with dollar symbols (for example).
Replace \{(\d+)\} with $\1$
The parenthesis in the regex "captures" the enclosed portion and it can be accessed in the replacement string using \1 syntax. So if you have multiple capturing groups, the first one is \1 and second one is \2 etc.
Some regex flavors follow $1 instead of \1 - in that case you should escape explicit $ symbol as $$ in the replacement string. Also, the \ character itself needs to be escaped as usual in the strings.
The curly braces are special characters and hence need to be escaped.
Use a capturing group: replace \{(\d+)\} with $\1$.