search/replace for multiple terms in a "template"

search/replace for multiple terms in a "template"

8
NewbieNewbie
8

    Aug 17, 2006#1

    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

    6,686585
    Grand MasterGrand Master
    6,686585

      Re: search/replace for multiple terms in a

      Aug 19, 2006#2

      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
      Best regards from an UC/UE/UES for Windows user from Austria

      8
      NewbieNewbie
      8

        Aug 23, 2006#3

        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

        6,686585
        Grand MasterGrand Master
        6,686585

          Aug 23, 2006#4

          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.
          Best regards from an UC/UE/UES for Windows user from Austria

          8
          NewbieNewbie
          8

            Re: search/replace for multiple terms in a

            Sep 07, 2006#5

            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 :-)