Regexp recursive find/replace in Notepad++ - regex

I am wondering if it is possible to write a Regular Expression in Notepad++, allowing me to modify an SQL INSERT script into DELETE.
Below is an example of what I am trying to do.
Input:
INSERT INTO table1 (xxxx, yyyy, zzzz, ....) VALUES (blah1111, foo2222, 3333333, ....);
Output:
DELETE FROM
table1
WHERE
AND xxxx = 'blah1111'
AND yyyy = 'foo2222'
AND zzzz = '3333333'
AND ....;
I have tried to use recursion, but i don't know how to properly make references for each recursion step.
My actual RegEx:
Find script: ((\w+)(?R)?, )
Replace script: (?1) =

I don't know how to do write recursive regular expressions in Notepad++, but you can use macros to automate at least part of the conversion. First you can run the RegEx
Find what: insert into (\w+) (\([^)]*\)) values (\([^)]*\));
Replace with: \2\n\3\nDELETE FROM\n\1\nWHERE\n
to get the basic structure of the DELETE script with two buffer lines above. Then you click Macro -> Start Recording and press Ctrl-Home, right arrow, Ctrl-Shift-right arrow, Ctrl-x, delete, delete, Ctrl-End, Tab, Ctrl-V, =, ', to move the first table column's name in the right position and continue until you have the
WHERE
AND xxxx = 'blah1111'
correctly. Then you click on Stop Recording and playback the macro until all the lines are generated correctly.
You can also try to add my recorded macro to %APPDATA%\Notepad++\shortcuts.xml directly:
<Macro name="ReorderSQL" Ctrl="no" Alt="no" Shift="no" Key="0">
<Action type="0" message="2316" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2306" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2442" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2177" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2180" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2180" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2318" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2327" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2179" wParam="0" lParam="0" sParam="" />
<Action type="1" message="2170" wParam="0" lParam="0" sParam=" " />
<Action type="1" message="2170" wParam="0" lParam="0" sParam="=" />
<Action type="1" message="2170" wParam="0" lParam="0" sParam=" " />
<Action type="0" message="2316" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2306" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2300" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2442" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2177" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2180" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2180" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2318" wParam="0" lParam="0" sParam="" />
<Action type="1" message="2170" wParam="0" lParam="0" sParam="&apos;" />
<Action type="0" message="2179" wParam="0" lParam="0" sParam="" />
<Action type="1" message="2170" wParam="0" lParam="0" sParam="&apos;" />
<Action type="1" message="2170" wParam="0" lParam="0" sParam="
" />
<Action type="1" message="2170" wParam="0" lParam="0" sParam="
" />
</Macro>

Related

How to Create Variable Definitions from Phrases using Regexes (Notepad++)

Suppose we have a list of phrases - words separated by spaces. And suppose we want to define a bunch of variables based on these phrases such that the following hold:
Phrases already exist and are surrounded by quotes (if not, you can easily use a regex to achieve this)
Phrases only contain letters (this actually isn't true for me in practice, but I can handle those cases manually)
Variable name, followed by an equals sign, should precede the phrase
Variable name should be a lowerCamelCase version of the phrase
Example
Input
"hello World"
"foo bAr"
Expected Output
helloWorld = "hello World"
fooBar = "foo bAr"
Use Case
Often in my line of work I am presented with a bunch of constants which come from an Excel spreadsheet and I need to define a bunch of variables in code for them. The phrases have spaces in them, but the variables can't. I'd usually like to keep the variable names as close to the phrases as I can. I'd like a way to do it in bulk, without having to individually type out each variable name.
Notes
I have come up with a way to do this, which I want to record here in case I need it in future and in case others might need it. I also want to post it here because I have a feeling there are optimizations that can be made to my process, or at least alternatives.
I haven't found a single find/replace step that'll do everything for you, but I have managed to do it using a sequence of regexes, applied one after another. The first pulls out the content for the variable name and inserts the "=". The next one does the main heavy lifting and removes spaces and applies the correct casing. The final one ensures all variables begin with lowercase letters. Apply them in sequence to achieve the desired result.
Regex #1
All we're doing here is pulling content out of the quotes and inserting it on the left hand side.
Note: here and below, I need to use this character for whitespace because SO doesn't render it correctly: ␣. So replace that with a space when you use this or other regexes in this answer.
Find: "(.+)"
Replace: ␣\1 = "\1" (note the leading space)
In our example, after this step, we end up with:
hello World = "hello World"
foo bAr = "foo bAr"
Regex #2
Here, we want to match each word on the left hand side, with the goal of removing the whitespace and simultaneously fixing the casing.
Find: ␣(\S)(\S+)(?=.*=) (note the leading space)
Replace: \u\1\L\2 (absence of space in replacement pattern achieves the removal of the space)
After this step, we end up with:
HelloWorld = "hello World"
FooBar = "foo bAr"
Correct, except for the first letter of each variable name.
Regex #3
This fixes the leading characters to be lowercase:
Find: ^(.)
Replace: \l\1
After this step, our output is as desired:
helloWorld = "hello World"
fooBar = "foo bAr"
Optional Regex #4 (Remove Invalid Characters)
Though the requirement assumed all letters, this is often not the case. First, you may want some numbers in there. Second, there may be junk like parentheses. In this case, just do a find/replace with the replace expression empty for the following find expression:
[^\w\r\n](?!=)(?=.*=)
What that does is first matches negatively to anything that's not a letter, a digit, an underscore or an end of line character. It then ensures that the match is followed by an = down the line but not immediately followed by an =, meaning the space before the = is preserved.
As a Macro
Rather than manually do all 4 steps above, you can record them as a macro and save it to your Notepad++. Or just paste the XML below inside the <Macros> XML element in the file shortcuts.xml inside %appdata%\Notepad++. If you do paste, the shortcut is ctrl+alt+shift+V, but you can change that to whatever you want:
<Macro name="DefineVariables" Ctrl="yes" Alt="yes" Shift="yes" Key="86">
<Action type="3" message="1700" wParam="0" lParam="0" sParam="" />
<Action type="3" message="1601" wParam="0" lParam="0" sParam="(.+)" />
<Action type="3" message="1625" wParam="0" lParam="2" sParam="" />
<Action type="3" message="1602" wParam="0" lParam="0" sParam=' \1 = "\1"' />
<Action type="3" message="1702" wParam="0" lParam="768" sParam="" />
<Action type="3" message="1701" wParam="0" lParam="1609" sParam="" />
<Action type="3" message="1700" wParam="0" lParam="0" sParam="" />
<Action type="3" message="1601" wParam="0" lParam="0" sParam=" (\S)(\S+)(?=.*=)" />
<Action type="3" message="1625" wParam="0" lParam="2" sParam="" />
<Action type="3" message="1602" wParam="0" lParam="0" sParam="\u\1\L\2" />
<Action type="3" message="1702" wParam="0" lParam="768" sParam="" />
<Action type="3" message="1701" wParam="0" lParam="1609" sParam="" />
<Action type="3" message="1700" wParam="0" lParam="0" sParam="" />
<Action type="3" message="1601" wParam="0" lParam="0" sParam="^(.)" />
<Action type="3" message="1625" wParam="0" lParam="2" sParam="" />
<Action type="3" message="1602" wParam="0" lParam="0" sParam="\l\1" />
<Action type="3" message="1702" wParam="0" lParam="768" sParam="" />
<Action type="3" message="1701" wParam="0" lParam="1609" sParam="" />
<Action type="3" message="1700" wParam="0" lParam="0" sParam="" />
<Action type="3" message="1601" wParam="0" lParam="0" sParam="[^\w\r\n](?!=)(?=.*=)" />
<Action type="3" message="1625" wParam="0" lParam="2" sParam="" />
<Action type="3" message="1602" wParam="0" lParam="0" sParam="" />
<Action type="3" message="1702" wParam="0" lParam="768" sParam="" />
<Action type="3" message="1701" wParam="0" lParam="1609" sParam="" />
</Macro>

url rewriting of IIS

with some hit and trail, i managed to remove the extention of the pages which i view for my website, now i want to replace all the ? and = and the & signs with backslash /, I am really Lost now, how do i write that rule in my web config
My Web.Config File:
<rewrite>
<rules>
<rule name="Redirect .cfm extension" stopProcessing="false">
<match url="^(.*).cfm$" ignoreCase="true" />
<conditions logicalGrouping="MatchAny">
<add input="{URL}" pattern="(.*).cfm$" ignoreCase="false" />
</conditions>
<action type="Redirect" url="{R:1}" redirectType="Permanent" />
</rule>
<rule name="hide .cfm extension" stopProcessing="true">
<match url="^(.*)$" ignoreCase="true" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}.cfm" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:0}.cfm" />
</rule>
</rules>
</rewrite>
with the above, i managed to get a page like this
http://website.ca/graphics?mode=Graphics%20Design%20%C2%BB%20Business%20cards&catID=35&section=graphics
the graphics? is the one which was before graphics.cfm?

IIS: Regex Including Dot/Period

I have the following rules. The second works but the first doesn't seem to to fire. For example, URL in question for the first rule is index.cfm?section=artists.az&id=22707 and for the 2nd rule which works, the URL is index.cfm?section=artists&id=22707
<rule name="Artists: AZ" stopProcessing="true">
<match url="^index\.cfm$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_METHOD}" pattern="^POST$" negate="true" />
<add input="{QUERY_STRING}" pattern="^section=artists\.az&id=([^=&]+)$" />
</conditions>
<action type="Rewrite" url="artist.php?id={C:1}" appendQueryString="false" />
</rule>
<rule name="Artists: index.cfm" stopProcessing="true">
<match url="^index\.cfm$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_METHOD}" pattern="^POST$" negate="true" />
<add input="{QUERY_STRING}" pattern="^section=artists&id=([^=&]+)$" />
</conditions>
<action type="Rewrite" url="artist.php?id={C:1}" appendQueryString="false" />
</rule>
ANy ideas?

IIS7 URL Rerwrite - how to replace all underscores with hyphens in a Regex?

I am using the URL Rewrite feature in IIS7 to turn the URL:
/main.asp?category=Name_Of_A_Product
Into:
/category/name-of-a-product/
I have created the redirect & rewrite rules below which do the majority of the work, except I cannot find a way of replacing the underscores with hyphens.
Each URL can have between zero and many underscores and I'm trying to replace them in a single regular expression, to avoid chains of 301 redirects (as I believe that is bad for SEO).
Do you know how (or if) this is can be done?
<rule name="Redirect REAL to FRIEDNLY" enabled="true" stopProcessing="true">
<match url="^main\.asp$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_METHOD}" pattern="^POST$" negate="true" />
<add input="{QUERY_STRING}" pattern="^category=([^=&]+)($|&(.*))$" />
</conditions>
<action type="Redirect" url="category/{ToLower:{C:1}}/" appendQueryString="false" />
</rule>
<rule name="Rewrite FRIEDNLY to REAL" stopProcessing="false">
<match url="^category/([^/]+)/?$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="main.asp?category={R:1}" />
</rule>
Unfortunately IIS7 has a few limitations:
you can only capture 9 groups C:1 ... C:9
there is only one string function and that's ToLower
Because of that you'll be limited to a URL with a maximum of 9 words separated by max 8 underscores (eg. /main.asp?category=One_Two_Three_Four_Five_Six_Seven_Eight_Nine) and you'll be forced to use 9 rewrite rules:
Single Word: /main.asp?category=Product
<rule name="Redirect REAL to FRIEDNLY 1" enabled="true" stopProcessing="true">
<match url="^main\.asp$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_METHOD}" pattern="^POST$" negate="true" />
<add input="{QUERY_STRING}" pattern="^category=([A-Za-z]+)$" />
</conditions>
<action type="Redirect" url="category/{ToLower:{C:1}}/" appendQueryString="false" />
</rule>
Two Words: /main.asp?category=Some_Product
<rule name="Redirect REAL to FRIEDNLY 2" enabled="true" stopProcessing="true">
<match url="^main\.asp$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_METHOD}" pattern="^POST$" negate="true" />
<add input="{QUERY_STRING}" pattern="^category=([A-Za-z]+)_([A-Za-z]+)$" />
</conditions>
<action type="Redirect" url="category/{ToLower:{C:1}}-{ToLower:{C:2}}/" appendQueryString="false" />
</rule>
Three Words: /main.asp?category=Some_New_Product
<rule name="Redirect REAL to FRIEDNLY 3" enabled="true" stopProcessing="true">
<match url="^main\.asp$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_METHOD}" pattern="^POST$" negate="true" />
<add input="{QUERY_STRING}" pattern="^category=([A-Za-z]+)_([A-Za-z]+)_([A-Za-z]+)$" />
</conditions>
<action type="Redirect" url="category/{ToLower:{C:1}}-{ToLower:{C:2}}-{ToLower:{C:3}}/" appendQueryString="false" />
</rule>
            ...            ...            ...            ...            ...            ...

Merging two lines into one - Notepad++

I have a line like this
assignee: Akebono Brake Industry Co. Ltd. ,
Fujitsu Limited application_no: 06/946,825
I want the output to be
assignee: Akebono Brake Industry Co. Ltd. , Fujitsu Limited
application_no: 06/946,825
To bring the application_no: 06/946,825 to the next line, I can find application_no: and replace it with \napplication_no: in my NOTEPAD++
But, how can I bring that string that spans to next line back to the first line? I mean what should I do to get the Fujitsu Limited to the line starting with assignee:
Any guidance please?
Since Extended is the only mode that handles the newlines correctly but you need to match with regular expressions, you will need to do this in two steps.
First, use a regex find and replace to add some recognizable token to the beginning of each line you want to move up, I used 'MATCH' but you could definitely change this.
Then, switch to Extended to search for a newline followed by the token, and replace it with an empty string to delete both the line break and the token.
Here is another solution. One step:
Search:
(^.*,.*$)\r\n([ A-Z]*[ ])
Replace:
\1\2\r\n
I am unfamiliar with notepad++, but surely there is a "/n" after the comma? Could you not just remove the char that creates the new line segment? ie: the inverse of what you are doing to application_no:
You can't do that with regular expressions due to a flaw in the Scintilla engine which Notepad++ uses. However, it works in "extended" find mode, so use that. Search for ,\r\n and replace with ,.
Change the \r\n to only \n on Linux, or to only \r on Mac OS.
I've just wrote that macro and works with your example.
Add this macro into shortcuts.xml, if you are using win7 file is located at C:\Users\{username}\AppData\Roaming\Notepad++
Just open your text file and get cursor to firts line, then run this macro.
<Macro name="stackoverflow" Ctrl="no" Alt="no" Shift="no" Key="0">
<Action type="3" message="1700" wParam="0" lParam="0" sParam="" />
<Action type="3" message="1601" wParam="0" lParam="0" sParam="application_no" />
<Action type="3" message="1625" wParam="0" lParam="0" sParam="" />
<Action type="3" message="1702" wParam="0" lParam="768" sParam="" />
<Action type="3" message="1701" wParam="0" lParam="1" sParam="" />
<Action type="0" message="2302" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2451" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2306" wParam="0" lParam="0" sParam="" />
<Action type="0" message="2326" wParam="0" lParam="0" sParam="" />
<Action type="3" message="1700" wParam="0" lParam="0" sParam="" />
<Action type="3" message="1601" wParam="0" lParam="0" sParam="application_no" />
<Action type="3" message="1625" wParam="0" lParam="0" sParam="" />
<Action type="3" message="1702" wParam="0" lParam="768" sParam="" />
<Action type="3" message="1701" wParam="0" lParam="1" sParam="" />
<Action type="0" message="2308" wParam="0" lParam="0" sParam="" />
<Action type="1" message="2170" wParam="0" lParam="0" sParam="
" />
<Action type="1" message="2170" wParam="0" lParam="0" sParam="
" />
</Macro>