Reply To: Need help on multi-line regular expression

Product Compare Forums Multi-Edit Support Need help on multi-line regular expression Reply To: Need help on multi-line regular expression

Bret Sutton

Not to belabor the point, but — well, I guess I’ll belabor the point. Like you, I love Perl regexes. They’re simply wow-powerful. And I understand the constraints you’re working under. But trying to use Perl regexes across line-ends is a big nuisance.

Going back to the one-two example presented earlier in the thread, suppose we want to combine the ‘one’ and ‘two’ lines into ‘one two’ lines. Then any of the following expressions will work:
[code:3j5lvijr]Search for: one *$two (Unix)
Replace with: \1

Search for: (?m)(one) *[\n\r]+(two) (Perl)
or: (?m)(one) *[\n\r]*$[\n\r]*(two)
Replace with: \1 \2[/code:3j5lvijr]
Perl expression #1 is more complex than the Unix expression, but we can define an alias <$^> for ‘ *[\n\r]+‘. We can’t hide the leading ignore-line-endings expression, so we’re left with [code:3j5lvijr](?m)(one)<$^>(two)[/code:3j5lvijr]
But let’s take this example:[code:3j5lvijr]one two
three four
one two
three nine
one two
five six
one seven
three four
one two
three four[/code:3j5lvijr]
If we want to append ‘three four’ to ‘one two’, we use the same technique as above. But suppose we want to have the ‘three’ start in column 20; so we use a macro to do it:[code:3j5lvijr]Search for: (?m)(two)<$^>(three)
Replace with: \1^!(NWSCURSR^CURSOR_TO_COL /C=20)\2[/code:3j5lvijr]
where the macro does what you think it does. (The position of the caret was established by trial and error to get the ‘three’ to go to column 20.) Try this search-and-replace and you may be surprised at the result. Try the caret in other positions, and you will also get strange results.

In order to get this to work properly, I had to include the entire second line in the search string, with the exception of trailing CR/LF characters:[code:3j5lvijr]Search for: (?m)(two)<$^>(three.*?)[\n\r]*?$
Replace with: \1^!(NWSCURSR^CURSOR_TO_COL /C=20)\2[/code:3j5lvijr]

Years ago, Dan told me


The template macro tracks the positon of the cursor based upon context. If the cursor is moved by an external macro without updating the globals the template macro uses, things sometimes don’t work as expected. Try adding the following two lines after the Goto_Col statement in your macro.

g_Original_Col = C_Col;
g_TmpCrCol = C_Col;

Dan[/quote:3j5lvijr] so those statements are included in the CURSOR_TO_COL macro. For the purposes of this test, I tried removing them; but obtained the same results.

Looking at the most recent example up there, you can see that it would be really cool to be able to pass parameters to an alias, so that I could code an alias <unsplit> as ‘!(?m)(#1)[\n\r]+(#2)[\n\r]*?$‘ and then use it maybe like this:[code:3j5lvijr]Search for: <unsplit /two/three/>
Replace with: \1^!(NWSCURSR^CURSOR_TO_COL /C=20)\2[/code:3j5lvijr]
where, of course, the delimiters in the search string (shown above as slashes) could be any character not otherwise found in the string.

I hope I got all those expressions right…