Regular expression look-back matches correctly but doesn't replace in Notepad++ [duplicate] - regex

I have the following CSS markup.
.previous-container{
float:left;
}
.primary-commands {
float:right;
}
Using the regex syntax search (?<=[\s,;])([a-zA-Z\-]+): it highlights the CSS property name as expected, however, upon clicking replace nothing is replaced. I have tried using group token syntax in replace line e.g. $[nth group] and any plain literal string replacement. No matter my attempts it will not replace the matched string with anything. I am using notepad++ version 6.7.5. Perhaps there is something obvious I am missing here?

Based on comments to the original question here are some work-arounds that solved my problem.
Option #1
Replace the lookbehind portion of the regex statement (?<=[\s,;]) with a simple non-lookbehind group matching statement such as ([\s,;]). This will continue to limit search results to strings beginning with the specified characters in the lookbehind. The only caveat is that in my replacement string e.g. $1 $2 I would need to leave out the undesired matched characters that should not be a part of the replacement string.
Option #2
Use the "Replace All" button. It will perform replacements correctly when using a positive lookbehind in your regex statement as opposed to using the "Replace" button for single replacement.
I went with Options #1 only because it achieves what I need while allowing me to still perform a single replacement at a time. With larger documents I don't want to use "Replace All" until I have thoroughly tested my regex expression.

Related

VSCode Regex Find/Replace In Files: can't get a numbered capturing group followed by numbers to work out

I have a need to replace this:
fixed variable 123
with this:
fixed variable 234
In VSCode this matches fine:
fixed(.*)123
I can't find any way to make it put the capture in the output if a number follows:
fixed$1234
fixed${1}234
But the find replace window just looks like this:
I read that VSCode uses rust flavoured rexes.. Here indicates ${1}234 should work, but VSCode just puts it in the output..
Tried named capture in a style according to here
fixed(?P<n>.*)123 //"invalid regular expression" error
VSCode doesn't seem to understand ${1}:
ps; I appreciate I could hack it in the contrived example with
FIND: fixed (.*) 123
REPL: fixed $1 234
And this does work in vscode:
but not all my data consistently has the same character before the number
After a lot of investigation by myself and #Wiktor we discovered a workaround for this apparent bug in vscode's search (aka find across files) and replace functionality in the specific case where the replace would have a single capture group followed by digits, like
$1234 where the intent is to replace with capture group 1 $1 followed by 234 or any digits. But $1234 is the actual undesired replaced output.
[This works fine in the find/replace widget for the current file but not in the find/search across files.]
There are (at least) two workarounds. Using two consecutive groups, like $1$2234 works properly as does $1$`234 (or precede with the $backtick).
So you could create a sham capture group as in (.*?)()(\d{3}) where capture group 2 has nothing in it just to get 2 consecutive capture groups in the replace or
use your intial search regex (.*?)(\d{3}) and then use $` just before or after your "real" capture group $1.
OP has filed an issue https://github.com/microsoft/vscode/issues/102221
Oddly, I just discovered that replacing with a single digit like $11 works fine but as soon as you add two or more it fails, so $112 fails.
I'd like to share some more insights and my reasoning when I searched for a workaround.
Main workaround idea is using two consecutive backreferences in the replacement.
I tried all backreference syntax described at Replacement Strings Reference: Matched Text and Backreferences. It appeared that none of \g<1>, \g{1}, ${1}, $<1>, $+{1}, etc. work. However, there are some other backreferences, like $' (inserts the portion of the string that follows the matched substring) or $` (inserts the portion of the string that precedes the matched substring). However, these two backreferences do not work in VS Code file search and replace feature, they do not insert any text when used in the replacement pattern.
So, we may use $` or $' as empty placeholders in the replacement pattern.
Find What:      fix(.*?)123
Replace With:
fix$'$1234
fix$`$1234
Or, as in my preliminary test, already provided in Mark's answer, a "technical" capturing group matching an empty string, (), can be introduced into the pattern so that a backreference to that group can be used as a "guard" before the subsequent "meaningful" backreference:
Find What: fixed()(.*)123 (see () in the pattern that can be referred to using $1)
Replace With: fixed$1$2234
Here, $1 is a "guard" placeholder allowing correct parsing of $2 backreference.
Side note about named capturing groups
Named capturing groups are supported, but you should use .NET/PCRE/Java named capturing group syntax, (?<name>...). Unfortunately, the none of the known named backreferences work replacement pattern. I tried $+{name} Boost/Perl syntax, $<name>, ${name}, none work.
Conclusion
So, there are several issues here that need to be addressed:
We need an unambiguous numbered backerence syntax (\g<1>, ${1}, or $<1>)
We need to make sure $' or $` work as expected or are parsed as literal text (same as $_ (used to include the entire input string in the replacement string) or $+ (used to insert the text matched by the highest-numbered capturing group that actually participated in the match) backreferences that are not recognized by Visual Studio Code file search and replace feature), current behavior when they do not insert any text is rather undefined
We need to introduce named backreference syntax (like \g<name> or ${name}).

Find and replace in Google Spreadsheet using Regular Expressions

I would like to use the Google Spreadsheet Find and Replace function with the "Search using regular expressions" function activated to do a search and replace in my document.
Use case: Some of my cells contain erroneous linefeed characters at the end (leftovers from paste operation by some of the editors).
I'm using the following pattern to successfully find the cells
.*\012$
Is there some syntax for the "Replace with" field that lets me replace the cell's content by the string I found minus the \012 character at the end?
The Google Spreadsheet documentation does not contain any relevant information. https://support.google.com/docs/answer/62754?hl=en
Here's a screenshot of the box
You may use a capturing group (...) in the pattern around the part you want to keep, and use a $1 backreference in the replacement:
(.*)\012$
to replace with $1.
See the regex demo.

Notepad++ Regex Find/Replace Using Look Behind not Working

I have the following CSS markup.
.previous-container{
float:left;
}
.primary-commands {
float:right;
}
Using the regex syntax search (?<=[\s,;])([a-zA-Z\-]+): it highlights the CSS property name as expected, however, upon clicking replace nothing is replaced. I have tried using group token syntax in replace line e.g. $[nth group] and any plain literal string replacement. No matter my attempts it will not replace the matched string with anything. I am using notepad++ version 6.7.5. Perhaps there is something obvious I am missing here?
Based on comments to the original question here are some work-arounds that solved my problem.
Option #1
Replace the lookbehind portion of the regex statement (?<=[\s,;]) with a simple non-lookbehind group matching statement such as ([\s,;]). This will continue to limit search results to strings beginning with the specified characters in the lookbehind. The only caveat is that in my replacement string e.g. $1 $2 I would need to leave out the undesired matched characters that should not be a part of the replacement string.
Option #2
Use the "Replace All" button. It will perform replacements correctly when using a positive lookbehind in your regex statement as opposed to using the "Replace" button for single replacement.
I went with Options #1 only because it achieves what I need while allowing me to still perform a single replacement at a time. With larger documents I don't want to use "Replace All" until I have thoroughly tested my regex expression.

Regex to insert text BEFORE a line containing a match?

I have a bunch of artists that are named in this fashion:
Killers, The
Treatment, The
Virginmarys, The
I need them to look like
The Killers
The Treatment
The Virginmarys
I'm able to match the lines with , The ((^|\n)(.*, The) is what I've used) but the more advanced syntax is eluding me. I can use regex on the replacement syntax as well (it's for a TextPipe filter so it might as well be for Notepad++ or any other Regex text editor).
You should be able to use the following:
Find: (\S+),\s\S*
Replace: The $1
Or include the The..
Find: (\S+),\s+(\S+)
Replace: $2 $1
Depending on your editor, you may be better off using \1, \2, and so on for capture groups.
Since you need to specifically capture the title before the comma, do so:
(^|\n)(.*), The
And replace it putting the "the" in the right place:
\1The \2
Regular expressions define matches but not substitutions.
How and in which way you can perform substitutions is highly dependant on the application.
Most editors that provide regular expression support work on a line per line basis.
Some of them will allow substitutions such as
s/^(.*Banana)/INSERTED LINE\n\1/
which would then insert the specific pattern before each match. Note that others may not allow newlines in the substitution pattern at all. In VIM, you can input newlines into the command prompt using Ctrl+K Return Return. YMMV.
In Java, you would just first print the insertion text, then print the matching line.

Regex for finding substrings using Grep Console in Eclipse

I am using Grep Console in Eclipse to highlight lines in the console output that contain characters, e.g. cancel, based on a regex. The characters may have a symbol preceding and/or following it, may be surrounded by spaces, or may be substrings. In other words, I want to match the following lines (regardless of case):
The flight was cancelled.
[Cancelled] Flight 101
Are they going to cancel it?
What is the regex that I need to use to highlight these lines?
As acdcjunior already explained, you basically just need a case insensitive regular expression to match "cancel".
If you already have your output in the console, the easiest way to create this expression is to just select the word "cancel" in the output, then right click and select "Add Expression" from the context menu. A submenu will you select a group to which the new expression will be added, or create a new one. The expression item will then be created, using the following expression:
(\Qcancel\E)
Be sure to uncheck the "Case sensitive" checkbox, which is enabled by default for performance reasons and would prevent the expression from matching your second line with the capital 'C'.
This is basically the same expression acdcjunior provided, with a few differences:
The .* matchers at the beginning and end of the expression are not included, as they are not necessary. Expressions will always match substrings anywhere in a line unless the $ or ^ matchers are used to specifically refer to the beginning or end of a line.
The expression is also wrapped in parentheses to create a capture group, allowing you to assign a style not only to the entire line containing the string cancel, but also to that string itself. You can leave out the parentheses if you don't want to style that string.
\Q and \E are always included when creating an expression from a selected text string to make sure that no characters from the selected string are interpreted as special expression characters. In this case, this not necessary, as cancel only contains word characters.
This means that in your case, the simplest sufficient expression is just:
cancel
This expression also works if you use it as a "quick expression", as suggested by acdcjunior, though there is no real need for this. The idea behind quick expressions is that very long lines in the console can considerably slow down pattern matching. Grep Console therefore has a configurable limit to how many characters in each line will be matched with the configured expressions. Any characters after this limit in long lines are ignored, which means that lines which contain keywords only after the limit will not be recognised and therefore not styled.
If you configure a quick expression, every line is first matched with this expression, and only if the match is positive will the "normal" expression be used. In this case, the expressions are matched against the entire line. The quick expression should therefore be as simple as possible, so as not to slow down the matching too much.
In your case, using cancel as a quick expression and leaving the normal expression blank works because first the quick expression is positively matched against your line, and then the blank expression matches as well. If you have very long lines, it may cost you some performance though, as the quick expression will ignore the length limits explained above. Also, quick expression don't use capture groups, so you can't highlight the cancel string with a separate style in this case.
Use:
.*(\Qcancel\E).*
And do not check "Case sensitive".
Or just cancel in the "Quick expression" text box.