Regular Expressions and Scripts - Worked Example

Programmer’s Notepad has great support for Regular Expressions baked in, supporting much more than the restricted syntax that many Scintilla-based editors provide. For example, did you know that you can use negative lookarounds to find text that doesn’t contain a pattern? This regular expression matches any line that doesn’t contain “not here”:

^((?!not here).)*$

Sometimes I find myself repeating the same set of Search/Replace operations in order to format text. If I’m going to do this more than a couple of times, I record a script using PyPN to make things easier for myself. Today I was turning text like this:

[sourcecode language=”java”] LogStep(“Do something”); MyClass.DoReallyCleverStuff(); MyClass.VerifySomethingAwesome();

LogStep("Do another thing");
MyClass.VerifySomethingBad(); [/sourcecode]

Into text like this:

Do something Do another thing

There are many ways to do something like this, and I could have written a PyPN script by hand to do it. However, combining Regular Expressions and Script Recording means I can do this without a lot of manual code effort. Here’s what I did:

  1. Tools > Record Script

  2. Replace All: ^((?!LogStep).)*$ with (nothing)

  3. Replace All: (\r\n){2,} with \r\n

  4. Replace All: \s*LogStep\("([^"]+)"\); with \1

  5. Tools > Stop Recording

At the end of this Programmer’s Notepad added a script to the Scripts window (Recorded\New Script) and placed the code for that script in a new editor window. Because I wanted to keep the script for future use, I changed it’s name and saved it to C:\Program Files\Programmer’s Notepad\Scripts. Here’s the script (which I reduced slightly for posting here):

[sourcecode language=”python”] import pn, scintilla

@script(“Clean Up Log Steps”, “Testing”) def CleanUpLogSteps(): doc = pn.CurrentDoc() sci = scintilla.Scintilla(doc) opt = pn.GetUserSearchOptions() opt.FindText = u’^((?!LogStep).)*$’ opt.MatchWholeWord = False opt.MatchCase = False opt.UseRegExp = True opt.SearchBackwards = False opt.LoopOK = True opt.UseSlashes = False opt.ReplaceText = u’’ opt.ReplaceInSelection = False doc.ReplaceAll(opt) # When recording, the result of this operation was: pn.FindNextResult(37)

opt.FindText = u'(\\r\\n\\r\\n){2,}'
opt.ReplaceText = u'\\r\\n'
# When recording, the result of this operation was: pn.FindNextResult(16)

opt.FindText = u'\\s*LogStep\\("([^"]+)"\\);'
opt.ReplaceText = u'\\1'
# When recording, the result of this operation was: pn.FindNextResult(10) [/sourcecode]

If I was going to use this script a lot, I could bind it to a shortcut key in Tools > Options > Keyboard.