search/replace for multiple terms in a "template"

Help with writing and playing macros

search/replace for multiple terms in a "template"

Postby Krivo » Thu Aug 17, 2006 7:53 am

Hi,

I have a challenge on how to search/replace for multiple terms in a "template" and add the "processed" templates into a new file.

Example:

Template file:
return_Ref_ex1_V_summer = check_V_summer_on_return (return_Ref_ex1);
return_Ref_ex2_V_winter = check_V_winter_on_return (return_Ref_ex2);
return_Ref_ex_DN = check_DN_on_return (return_Ref_ex3);


Everywhere Ref_ex1 is written I want to exchange with a certain keyword e.g. pos_a1, Ref_ex2 to pos_a2, Ref_ex3 to pos_a3

But I also want to do the same 'procedure' for 'pos_b', 'pos_c' etc until 'pos_x'.

I hoped to have a file where I could specify how to exchange values - example:

Ref_ex1; pos_a1; Ref_ex2; pos_a1; Ref_ex3; pos_a3;
Ref_ex1; pos_b1; Ref_ex2; pos_b2; Ref_ex3; pos_b3;
etc.

But this could possibly be written in a much smarter way :-)

I already made a setup where there is only one Ref_ex - i.e. only one keywork can be exchanged. I'm using 4 different open documents to do the this. 1: template, 2: workspace; 3: the 'translated' keywords; 4: the final document.

I tried using clipboard but for some reason they seems to be playing a trick on me - can't get them to work.

I'm using version 12.10a

Input much appreciated - and pls let me know if there is a lack of information :-D

Best regards

Krivo



Present macro setup:
InsertMode
ColumnModeOff
HexOff
UnixReOff
Loop 50
SelectAll
StartSelect
Copy
EndSelect
NextDocument
Paste
NextDocument
GotoLine 1
Key HOME
StartSelect
Key END
IfSel
Else
ExitLoop
EndIf
Copy
PreviousDocument
Find RegExp "ref_ex"
Replace All "^c"
SelectAll
Copy
NextDocument
NextDocument
Paste
PreviousDocument
Key BACKSPACE
EndSelect
Key BACKSPACE
Key DEL
PreviousDocument
PreviousDocument
EndLoop

My 'translated' keyword document look like this:
pos_a
pos_b
pos_c
pos_d
pos_e
pos_f
pos_g
pos_h
pos_i
pos_j
pos_k
pos_l
pos_m
pos_n
pos_o
pos_p
pos_q
pos_r
pos_s
pos_t
pos_u
pos_v
pos_x
User avatar
Krivo
Newbie
 
Posts: 8
Joined: Thu Nov 10, 2005 12:00 am

Re: search/replace for multiple terms in a

Postby Mofi » Sat Aug 19, 2006 10:30 am

I have needed a while to create this macro and write the explanation. The following macro needs some preparation.

The first opened file which must have the focus is your template file. It's important that the last line of this file is terminated with a line termination (CRLF for DOS). The macro adds a line termination at the last line, if the template file does not have one.

The second file opened which has currently not the focus is your keywords file:

Code: Select all
Ref_ex1;pos_a1;Ref_ex2;pos_a2;Ref_ex3;pos_a3;
Ref_ex1;pos_b1;Ref_ex2;pos_b2;Ref_ex3;pos_b3;
Ref_ex1;pos_c1;Ref_ex2;pos_c2;Ref_ex3;pos_c3;

Note: I have deleted the spaces after every semicolon.

It's important here too that the last line is terminated - macro checks this. It's also important that there are not trailing spaces at end of any line (macro trims it) and there are no blank lines (not checked by the macro).

The terms - not words, you can also use strings with spaces - are delimited by a semicolon. It's important that at the end of every line also a semicolon exists - macro does not check this. It's finally also important that every line contains an even number of terms - search term and replace term. The number of pair terms is not important. It can be 2, 4, 6, 8, ... and even can vary from line to line although this would not make sence for your template.

If you want also checks for blank lines, semicolons at the end of every line and always pair of terms you can insert an appropriate macro code. But I think it is not needed, isn't it.

And there should be no replace string which is identical with any search string or you will not get what you want.

Ah, I have forgotten it nearly. The keywords file must be a DOS file or is opened with automatic conversion to DOS or at least you must have the configuration option On Paste convert line ending to destination type (UNIX/MAC/DOS) enabled. The generated file is always a DOS file which of course you can change to Unix at the end of the macro with the command DosToUnix.


Okay, back to the macro. 2 files are opened, the keywords file and the template file which has the focus.

First the macro checks the line termination of the last line of the template file and then copies the whole template file content into clipboard 9 and unselect it again.

After switching to the next document, hopefully the keyword file, again the termination of the last line is checked, the trailing spaces are deleted and the whole content is copied into clipboard 8.

Next a new DOS file is created and the keywords are pasted at top of the file. Well, I write always my macros with as less document switches as possible because document switching slows down macro execution extremly.

So next the macro inserts a new line below the list of terms (keywords) with the special starting character ». It's important that no line above starts also with this character. This line is also bookmarked for faster finding it later. This bookmarked line divides the content of the new file into 2 sections - above are the search and replace terms, below is the template content.

Well, now once the template content must be inserted from clipboard 9 at the end of the new file and then the cursor is moved to top of the new file. Clipboard 9 will hold the template file content until the macro finishs after exiting the following loop.

The following loop assumes that the keyword file has had at least one line because it immediatelly starts with the terms (keywords) replace code.

All characters from start of the current line till the semicolon are cutted to clipboard 8. This is the string to search for. The ; is deleted and the next term till ; is cutted to clipboard 7. This is the replace string. The ; is again deleted.

It's not possible to search for string in clipboard 8 and replace it with the string in clipboard 7. There are no other lines allowed between the commands Find and Replace.

So the macro goes now to the bookmarked separator line and inserts the replace string here after the special character and selects it immediatelly again.

Now from this position below the other still existing terms to replace, a normal case-sensitive search and replace ALL is executed which replaces all occurences of the search string in clipboard 8 with the currently selected replace string.

The still selected replace string at the separator line is then deleted and the cursor is moved back to top of the file.

Well, maybe it would be better to bookmark always the first line of the template to process instead of only once the separator line because then only the bytes of the last inserted template content must be searched and replaced and not also always all already processed template lines. But I have not had success with this solution because the bookmark always suddenly disappears and I have not looked into it why.

If the character at top of the file is now a Carriage Return (decimal code 13, hex 0D), the macro has done all replaces for this template. If it is not a CR, simply continue with the next term pair.

The now empty keyword line terminated with CRLF is deleted. If the cursor is now at start of the separator line with the special character », all terms from the keyword files has been processed and so the bookmark is cleared and the separator line is deleted before the loop exits.

If there are more pairs of terms to do than goto end of the file and insert again the template file content still hold in clipboard 9 and continue the replace process from top of the file.

Last the 3 clipboards 7-9 used for this macro are cleared and the windows clipboard is selected before the macro exits.


You must enable the macro property Continue if a Find with Replace not found for this macro.

InsertMode
ColumnModeOff
HexOff
Clipboard 9
Bottom
IfColNum 1
Else
"
"
EndIf
SelectAll
Copy
EndSelect
Top
NextDocument
Clipboard 8
Bottom
IfColNum 1
Else
"
"
EndIf
Top
TrimTrailingSpaces
SelectAll
Copy
EndSelect
Top
NewFile
UnixMacToDos
Paste

"
Key UP ARROW
ToggleBookmark
Key DOWN ARROW
Clipboard 9
Paste
Top
Clipboard 8
Loop
StartSelect
Find Select ";"
Key LEFT ARROW
Cut
EndSelect
Key DEL
StartSelect
Find Select ";"
Key LEFT ARROW
Clipboard 7
Cut
EndSelect
Key DEL
GotoBookMark
Key RIGHT ARROW
Paste
Key HOME
Key RIGHT ARROW
StartSelect
Key END
Clipboard 8
Find MatchCase "^c"
Replace All "^s"
Delete
Top
IfCharIs 13
Key DEL
IfCharIs "»"
ToggleBookmark
DeleteLine
ExitLoop
Else
Bottom
Clipboard 9
Paste
Top
Clipboard 8
EndIf
EndIf
EndLoop
ClearClipboard
Clipboard 9
ClearClipboard
Clipboard 7
ClearClipboard
Clipboard 0
User avatar
Mofi
Grand Master
Grand Master
 
Posts: 4062
Joined: Thu Jul 29, 2004 11:00 pm
Location: Vienna

Re: search/replace for multiple terms in a "template"

Postby Krivo » Tue Aug 22, 2006 9:06 pm

Hi Mofi,

Again I must admire your performance in UE. Great respect !!

I had huge difficulties in getting things to work and as I can see there is a limitation which I think you haven't mentioned. A search string cannot be allowed to be a subset of another search string.

keyword-file:
Ref_ex;pos_a;
Ref_ex2;pos_a2;


Having such setup will make the macro loop because 'Ref_ex' is a subset of another search string 'Ref_ex2'

Can you see any solution for such setup - or would that just be the limitation of the macro?

Thanks in advance :-)

Krivo
User avatar
Krivo
Newbie
 
Posts: 8
Joined: Thu Nov 10, 2005 12:00 am

Re: search/replace for multiple terms in a "template"

Postby Mofi » Wed Aug 23, 2006 5:24 am

Well, the macro is written for terms. But if you don't use terms, only words (=strings which contain only 0-9A-Za-z and _ ) you could use the find option MatchWord addtionally to MatchCase. But this is not possible for you because the Ref_ex? keyword is also only a part of a larger word in the template file.

So in your case it would be better to avoid keywords which are substrings of other keywords. I avoid now always substring keywords when I define constants, variables, defines, typedefs, ... because of the same find and replace problem. I learned this also the hard way.

In your special case you could change the order of the keywords:

Ref_ex1;pos_a1;Ref_ex2;pos_a2;Ref_ex3;pos_a3;Ref_ex;pos_a;

That would solve the problem and it's the only solution for solving keywords with identical start string. First search for the longest keyword and replace it by something completely different, then the next a little bit shorter keyword (or with identical length but other characters), ... until the shortest keyword is replaced.
User avatar
Mofi
Grand Master
Grand Master
 
Posts: 4062
Joined: Thu Jul 29, 2004 11:00 pm
Location: Vienna

Re: search/replace for multiple terms in a

Postby Krivo » Wed Sep 06, 2006 8:06 pm

Hi,

just to follow up on this subject. I didn't get the macro to work when having the 'work-area' the same as the 'output-area'. The replace all seemed to destroy the multiple keyword functionality - because it replaced terms which I was going to use as keywords later on. Therefore I rearranged the macro to use more files - eventhough as Mofi states - this is a slower approach.

The procedure is as follows:

• Open first document which must hold the ‘template’
• Open the second document which must hold the keywords – must be a DOS file (see below in limitations)
• Set focus on the first document (holding the template) by selecting the document
• Run the macro ‘Multiple_replace’
• The processed document can be found as the last opened document.


An example could be like this:

Template file:
return_Ref_ex1_V_summer = check_V_summer_on_return (return_Ref_ex1);
return_Ref_ex2_V_winter = check_V_winter_on_return (return_Ref_ex2);
return_Ref_ex3_DN = check_DN_on_return (return_Ref_ex3);

Everywhere where Ref_ex1 is written another keyword must be inserted e.g. pos_a1. Same setup is needed for : Ref_ex2 to pos_a2
Ref_ex3 to pos_a3

The process must be done in a similar way for 'pos_b' and 'pos_c'.

The keyword file would look like this:
Ref_ex1;pos_a1;Ref_ex2;pos_a2;Ref_ex3;pos_a3;
Ref_ex1;pos_b1;Ref_ex2;pos_b2;Ref_ex3;pos_b3;
Ref_ex1;pos_c1;Ref_ex2;pos_c2;Ref_ex3;pos_c3;


The output document would look like:
return_pos_a1_V_summer = check_V_summer_on_return (return_pos_a1);
return_pos_a2_V_winter = check_V_winter_on_return (return_pos_a2);
return_pos_a1_DN = check_DN_on_return (return_pos_a3);
return_pos_b1_V_summer = check_V_summer_on_return (return_pos_b1);
return_pos_b2_V_winter = check_V_winter_on_return (return_pos_b2);
return_pos_b1_DN = check_DN_on_return (return_pos_b3);
return_pos_c1_V_summer = check_V_summer_on_return (return_pos_c1);
return_pos_c2_V_winter = check_V_winter_on_return (return_pos_c2);
return_pos_c1_DN = check_DN_on_return (return_pos_c3);


Limitations:
• The terms - not words, you can also use strings with spaces - are delimited by a semicolon. It's important that at the end of every line also a semicolon exists.
• Important that every line contains an even number of terms - search term and replace term. The number of pair terms is not important. It can be 2, 4, 6, 8, ... and even can vary from line to line.
• There should be no replace string which is identical with any search string or you will not get what you want.
• If any of the searched keywords are a subset of another keyword then such keyword must be placed later in the keyword file. In other words – first search for the longest keyword and replace it by something completely different, then the next a little bit shorter keyword (or with identical length but other characters), ... until the shortest keyword is replaced.
• The keywords file must be a DOS file or is opened with automatic conversion to DOS or at least you must have the configuration option On Paste convert line ending to destination type (UNIX/MAC/DOS) enabled.


The macro code:

InsertMode
ColumnModeOff
HexOff
Clipboard 9
Bottom
IfColNum 1
Else
"
"
EndIf
SelectAll
Copy
EndSelect
Top
NextDocument
Clipboard 8
Bottom
IfColNum 1
Else
"
"
EndIf
Top
TrimTrailingSpaces
SelectAll
Copy
EndSelect
Top
NewFile
UnixMacToDos
Paste

"
Key UP ARROW
ToggleBookmark
Key DOWN ARROW
NewFile
UnixMacToDos

"
Key UP ARROW
ToggleBookmark
Key DOWN ARROW
Bottom
Clipboard 9
Paste
Top
PreviousDocument
Clipboard 8
ClearClipboard
Loop
Top
Clipboard 8
ClearClipboard
StartSelect
Find Select ";"
Key LEFT ARROW
Cut
EndSelect
Key DEL
StartSelect
Find Select ";"
Key LEFT ARROW
Clipboard 7
Cut
EndSelect
Key DEL
NextDocument
GotoBookMark
Key RIGHT ARROW
Clipboard 7
Paste
Key HOME
Key RIGHT ARROW
StartSelect
Key END
Clipboard 8
Find MatchCase "^c"
Replace All "^s"
Delete
PreviousDocument
Top
IfCharIs 13
Key DEL
IfCharIs "»"
ToggleBookmark
DeleteLine
CloseFile NoSave
ExitLoop
Else
NextDocument
Bottom
Clipboard 9
Paste
PreviousDocument
Top
Clipboard 8
EndIf
EndIf
EndLoop
Top
DeleteLine
ClearClipboard
Clipboard 9
ClearClipboard
Clipboard 7
ClearClipboard
Clipboard 0


And thanks again to Mofi - without your input I would never have got this to work :-)
User avatar
Krivo
Newbie
 
Posts: 8
Joined: Thu Nov 10, 2005 12:00 am


Return to Macros