Regex replace within match - regex

In Notepad++ RegEx, I want to search for all strings starting with a tilde and terminating with \n, and within each match replace all spaces with non-breaking spaces.
That is, I want to find all instances of \~.*^, and within the resulting $0, replace all [Space]s with [Non-breaking Space].
Is this possible?

You can use the following to match:
(?:~|\G(?<!^))\S*\K\s
Or try:
(?:~|\G(?!^))\S*\K[ ]
And replace with non breaking space
See DEMO
Credits

With fixed-width pattern lookbehind regex engines (e.g., Perl):
s/(~.*?) {2,}/\1 /g
with variable-width pattern lookbehind regex engines:
s/(?<=\~.*) {2,}/ /g
or with Vim:
s/\(\~.*\)#<= \{2,}/ /g
I'm not sure about Notepad++. Hopefully you can work it out based on the above.

Related

How can I use regex to convert Uppercase text to lowercase text in combination with a look-ahead and look-behind

In the context of an XML file, I want to use the XML tags in a positive look-behind and positive look-ahead to convert a value to lowercase.
BEFORE:
<CONDITION NAME="ABC-DEF-GHI" DATE="DATE">
AFTER:
<CONDITION NAME="abc-def-ghi" DATE="DATE">
Pattern's tried from other questions/regex wiki that don't work.
1.
FIND:
(?<=(<CONDITION NAME="))(.+)(?=(" DATE="DATE"))
REPLACE:
\L0
FIND:
(?<=(<CONDITION NAME=".*))(\w)(?=(.*" DATE="DATE"))
REPLACE:
\L$1
Using VS Code 1.62.1
MAC OS Darwin x64 19.6.0
You don't need any capture groups if yo want to use lookarounds at the left and right side.
Instead of using .+ which is a broad match and can match too much, you can use a negated character class [^"]+ to match any character except a double quote, or you can use [\w-]+ to match 1 or more word characters or a hyphen:
(?<=<CONDITION NAME=")[^"]+(?=" DATE="DATE")
Regex demo
Replace with the full match using $0
\L$0
Another option is to use 2 capture groups with a single lookahead as lookarounds can be expensive, and replace with $1\L$2
(<CONDITION NAME=")([\w-]+)(?=" DATE="DATE")
Pattern 2 works. The replace value just needs to change from
\L$1 -> \L$2
Pattern 1 could also be used with \L$2 as the replace value.
This pattern works:
FIND:
(?<=(<CONDITION NAME=".*))(\w)(?=(.*" DATE="DATE"))
REPLACE:
\L$2
Make sure you make the other groups non-capturing:
(?<=(?:<CONDITION NAME="))(.+)(?=(?:" DATE="DATE"))
Or leave out the inner () altogether:
(?<=<CONDITION NAME=")(.+)(?=" DATE="DATE")
Or use $2 as replacement. Everything between standard () becomes a captured group, no matter where in the expression they are.
And be careful with .+, in this case [^"]+ is a much safer choice.

Notepad++: add parentheses to timestamps

I have text with timestamps for gaps in audio, e.g. "We met 51:33 at the bar". I need to add paretheses to timestamps to make them more readable: "We met (51:33) at the bar". How do I do that in Notepad++??
I already created a regex search and replace. It searches for \d\d:\d\d and replaces it with (\d\d:\d\d). Unfortunately, I get (dd:dd) everywhere.
You may enhance the regex a bit with lookarounds (?<!\d) and (?!\d) to make sure you get xx:xx not enclosed with other digits, and use backreference to the whole match ($&) in the replacement:
Search: (?<!\d)\d\d:\d\d(?!\d)
Replace: \($&\)
Note: the ( and ) must be escaped in the replacement pattern since NPP uses Boost conditional replacement pattern syntax.

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>

Multiline regex replacement in sed/vi

I need to replace this statement in a named.conf with regex
masters {
10.11.2.1;
10.11.2.2;
};
All my approaches with sed/vi do not work
%s/masters.*\}\;//g
does not match. Also tried with /s \s etc to match the newline.
In vim, you can force a pattern to match across newlines with \_, for example:
%s/masters {\_[^}]*};//g
It's important to replace .* with something more conservative like [^}]* if you prefix with \_, because * is greedy, so \_.* will try to match everything to the end of the document.

vim regex find and replace

I want to use a regex to replace some strings in my file. I search for:
%s/^ [a-z]*/ /
what I want to do is to replace every [a-z]* that have 2 whitespaces with the sane [a-z] prepended with 4 whitespaces. Is there any "inplace" replacement or how would I reach that with vim?
With best regards
:%s/ \([a-z]*\)/ \1/g
should do the job; beware of running this multiple times, though because the result of the replace will match the input pattern :)
I find it more straightforward to use the \ze object to define the end of the match:
:%s/ \ze[a-z]*/ /g
so the [a-z]* is not included in the replace, but just used to match the relevant spaces.