• Login
Community
  • Login

Find a text in multiline and replace text

Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
9 Posts 3 Posters 544 Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S
    shashi bhosale
    last edited by Jul 26, 2021, 7:03 PM

    I would like to find a block of text which can be multi-line or single line.

    1. It will start with find first
    2. it will end with dot/period.
    3. Would like to replace “find first” with " for first "
    4. period should be replaced with " : end . "
    5. if there is any no-error within the text it should get removed.

    Example 1.

    find first customer no-lock where custnum = “Number1” no-error.
    output should be
    For first customer no-lock where custnum = “Number1” : END .

    Example 2
    find first customer no-lock
    where custnum = “Number1”
    and Col1 = Val1
    and col2 = val2
    and col3 = val3
    no-error.
    output should be
    For first customer no-lock
    where custnum = “Number1”
    and Col1 = Val1
    and col2 = val2
    and col3 = val3
    : END.

    1 Reply Last reply Reply Quote 0
    • G
      guy038
      last edited by guy038 Aug 3, 2021, 6:28 PM Jul 26, 2021, 8:39 PM

      Hello, @shashi-bhosale and All,

      Very easy with regexes !

      • Open the Replace dialog ( Ctrl + H )

        • SEARCH (?s-i)find (?=first)(.+?)(?:no-error)?(?=\.$)

        • REPLACE For \1: END

        • Tick, preferably, the Wrap around option

        • Select the Regular Expression search mode

        • Click on the Replace All button

      Voila !


      Notes :

      • First, the part (?s-i) ensures that :

        • The dot regex char ( . ) matches any character, even EOL ones ( \r and \n ), due to the (?s) syntax

        • The search is processed in a sensitive way ( non-insensitive way ), due the the (?-i) syntax

      • Then, the part find (?=first) searches for the find string, with this exact case, followed with a space char

      • But, ONLY IF it is followed with the first string, with this exact case, due to the look-ahead structure (?=first)

      • Then the middle part (.+?) matches the smallest non-null multi-lines range of any character, from after the string find and the space char, stored as group 1, due to parentheses, till…

      • … An optional string no-error, with this exact case, stored in a non-capturing group and ONLY IF it is followed with an literal period char, ending the current line, due to the final syntax (?:no-error)?(?=\.$)

      • In replacement, we rewrite :

        • First the string For, followed with a space char

        • Then, the contents of group 1 ( \1 )

        • Finally, the literal string : END, with this exact case !

      Best Regards

      guy038

      1 Reply Last reply Reply Quote 2
      • S
        shashi bhosale
        last edited by Jul 28, 2021, 11:45 AM

        good except if there is spaces after no-error it doesnt work .

          find first ki.timeatt no-LOCK WHERE
          ki.TimeAtt.emp-num = ki.pcn.emp-num AND
          ki.TimeAtt.typecode = ki.pcn.typecode AND
          ki.TimeAtt.cdate = LvPCNDate NO-ERROR   .
        

        I want to ignore spaces or black new line and eliminate NO-ERROR .

        1 Reply Last reply Reply Quote 0
        • S
          shashi bhosale
          last edited by Jul 28, 2021, 6:40 PM

          Nothing in the whole block is case sensitive. Also i string could look like below too.
          find first
          ki.timeatt no-LOCK
          WHERE
          ki.TimeAtt.emp-num = ki.pcn.emp-num AND
          ki.TimeAtt.typecode = ki.pcn.typecode AND
          ki.TimeAtt.cdate = LvPCNDate
          NO-ERROR .

          1 Reply Last reply Reply Quote 0
          • G
            guy038
            last edited by guy038 Aug 3, 2021, 6:25 PM Jul 29, 2021, 11:17 AM

            Hi, @shashi-bhosale and All,

            Sorry for my late reply :-((

            So, for instance given this INPUT text :

              find         first ki.timeatt no-LOCK WHERE
              ki.TimeAtt.emp-num = ki.pcn.emp-num AND
              ki.TimeAtt.typecode = ki.pcn.typecode AND
              ki.TimeAtt.cdate = LvPCNDate NO-ERROR   .
            
            
            find first
            ki.timeatt no-LOCK
            WHERE
            ki.TimeAtt.emp-num = ki.pcn.emp-num AND
            ki.TimeAtt.typecode = ki.pcn.typecode AND
            ki.TimeAtt.cdate = LvPCNDate
            NO-ERROR. 
            

            The regex S/R, below :

            • SEARCH (?si)find\x20+(first.+?)no-error\x20*\.\x20*$

            • REPLACE For\x20\1:\x20END.

            should give the expected OUTPUT text :

              For first ki.timeatt no-LOCK WHERE
              ki.TimeAtt.emp-num = ki.pcn.emp-num AND
              ki.TimeAtt.typecode = ki.pcn.typecode AND
              ki.TimeAtt.cdate = LvPCNDate : END.
            
            
            For first
            ki.timeatt no-LOCK
            WHERE
            ki.TimeAtt.emp-num = ki.pcn.emp-num AND
            ki.TimeAtt.typecode = ki.pcn.typecode AND
            ki.TimeAtt.cdate = LvPCNDate
            : END.
            

            As you can see, I changed and simplified the global logic of the S/R :

            • The words/string find, first and no-error are searched whatever their case, due to the initial syntax (?i). So, for instance, the words Find, fIRsT and no-ERRORS will be matched !

            • The \x20+ syntax, between the two words find and first, represents any non-null range of space characters

            • The (first.+?) searches the smallest range of chars, beginning from word first, whatever its case, till the next string no-error, excluded and is stored as group1, due to the parentheses

            • Then, the part no-error\x20* looks for the string no-error, whatever its case, followed with an optional range of space characters

            • and the final part \.\x20$* searches for a literal dot char followed by optional space characters again, ending the current line

            • In replacement :

              • The part For\x20 replaces the word find followed with space char(s) by the word For, followed with a single space char

              • Then, the group 1 is rewritten ( \1 )

              • Finally, the part :\x20END. replaces the string no-error with optional space chars and a final . char by the string : END. with this exact case

            Cheers

            guy038

            1 Reply Last reply Reply Quote 1
            • S
              shashi bhosale
              last edited by Aug 3, 2021, 11:53 AM

              @guy038 said in Find a text in multiline and replace text:

              For\x20\1:\x20END.

              Thanks. This is great. Works fine.
              I would like to change this to a choice values.

              Find first phila.employee no-lock no-error.
              Find first oshk.employee no-lock no-error.
              Find first Germany.employee no-lock no-error.

              The search should find phila and oshk but ignore anything which is not Phila or Oshk.
              it should find first 2 lines and ignore 3rd line.

              1 Reply Last reply Reply Quote 0
              • G
                guy038
                last edited by guy038 Aug 3, 2021, 6:26 PM Aug 3, 2021, 6:24 PM

                Hello, @shashi-bhosale and All,

                OK. So the new S/R is, simply :

                • SEARCH (?si)find\x20+(first\x20(?:phila|oshk).+?)no-error\x20*\.\x20*$

                • REPLACE For\x20\1:\x20END.


                Notes :

                • I’ve just changed the part (first.+?), which represents the group 1, by the syntax (first\x20(?:phila|oshk).+?)

                • As you can see, *after the string first, whatever its case, I inserted the regex \x20(?:phila|oshk) containing, after the space char, a (?:••••••••) structure, known as a non-capturing group.

                • Inside this non-capturing group, it looks, either, for the string phila OR the string oshk, due to the alternation symbol |

                • Note that you may extend this list of alternatives, for instance, with the regex (?:phila|oshk|third_case|fourth_case|fifth_case...)

                Cheers,

                guy038

                1 Reply Last reply Reply Quote 1
                • S
                  shashi bhosale
                  last edited by Aug 3, 2021, 6:37 PM

                  Thanks a lot for help. What website you use to get explanation of the command ?

                  P 1 Reply Last reply Aug 3, 2021, 6:42 PM Reply Quote 0
                  • P
                    PeterJones @shashi bhosale
                    last edited by Aug 3, 2021, 6:42 PM

                    @shashi-bhosale said in Find a text in multiline and replace text:

                    Thanks a lot for help. What website you use to get explanation of the command ?

                    You could look in this forum’s FAQ section and find the FAQ entry about Where to find regular expression documentation. It links to the official Notepad++ regular expression documentation, as well as several external sites which are useful for learning about or experimenting with or describing the specifics of regular expressions.

                    1 Reply Last reply Reply Quote 1
                    5 out of 9
                    • First post
                      5/9
                      Last post
                    The Community of users of the Notepad++ text editor.
                    Powered by NodeBB | Contributors