Community
    • Login

    Regex find and replace string in different types of brackets

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    regex group replace
    4 Posts 3 Posters 75 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.
    • Евгений КЕ
      Евгений К
      last edited by PeterJones

      Hi there!
      I have some text. there is some string in it that can be in different types of brackets. For example:

      >Some String<
      

      or

      "Some string".
      

      I need to replace these strings, with New String, desired result:

      >New String<
      

      and

      "New String".
      

      I can find and replace >Some String< with >New String< (without any regex), then find and replace “Some String” with “New String” (without any regex).
      But if there is some regex expression to do replacement like by one step?
      —

      moderator added code markdown around text; please don’t forget to use the </> button to mark example text as “code” so that characters don’t get changed by the forum

      PeterJonesP 1 Reply Last reply Reply Quote 0
      • PeterJonesP
        PeterJones @Евгений К
        last edited by

        @Евгений-К ,

        One way to do it simultaneously is

        FIND = (>Some String<)|("Some String")
        REPLACE = (?1>New String<)(?2"New String")
        SEARCH MODE = Regular Expression

        But that’s “annoying” because you have to repeat the Some String and New String in the FIND and REPLACE.

        There are some fancy tricks using capture groups, either named or numbered, and control-flow assertions, to make sure that things balance correctly, and it will only match .

        FIND = (?'startwrap'(?'angled'>)|(?'quoted'"))\KSome String(?'endwrap'(?=(?('quoted')")(?('angled')<)))
        REPLACE = New String
        SEARCH MODE = Regular expression

        But as you can see, the FIND becomes rather complicated to save the “expense” of having Some String and New String twice. (You could theoretically do it with numbered capture groups instead, but getting the counts right, especially as you edit to make a third pair like {Some String}, would cause problems, so I used named groups so there was no ambiguity in the future. I will leave the “numbered group” version as an exercise to the interested reader.)

        So that’s two ways. Which is best depends on which you understand, and whether it’s going to be expanded in the future and/or done often. The most important thing with regex is that you understand what it’s doing, so that you don’t mess up your data.

        If you don’t understand a “single regex version” but can get it done in two simple search-and-replace that you fully understand, then two simple is probably better for you. (If it’s something you will be doing often, you can record the two search-and-replace into a macro, so that you can just play that macro in the future.)

        Евгений КЕ 1 Reply Last reply Reply Quote 0
        • guy038G
          guy038
          last edited by

          Hello, @евгений-к, @peterjones and All,

          Why not this simple S/R syntax :

          • FIND (?<=[>"])Some(?= String[<"])

          • REPLACE New

          Of course, check the Regular Expression search mode


          However, if you have mismatched delimiters, the solution above would match the expressions >Some String" and "Some String< as well :-((

          In order to restrict the matches to your two expressions >Some String< and "Some String"., you could use this second S/R :

          • FIND (?<=(>)|")Some(?= String(?(1)<|"))

          • REPLACE New

          >Some String<
          >Some String"
          "Some String".
          "Some String<
          

          Notes :

          • At beginning of the regex, the (?<=(>)|") part is a look-behind structure where we define the > character as the group 1

          • At the end of the search regex, the part (?(1)<|") is a conditional expression, inside the (?= String(?(1)<|")) look-ahead structure, which means :

            • Use the < delimiter if the group 1 is defined

            • Otherwise, use the " delimiter

          • In the middle of the regex, we’re just searching for the Some expression, IF preceded AND followed with the delimiters, that we then replace with the New expression

          Best Regards,

          guy038

          1 Reply Last reply Reply Quote 1
          • Евгений КЕ
            Евгений К @PeterJones
            last edited by

            @PeterJones said in Regex find and replace string in different types of brackets:

            @Евгений-К ,

            One way to do it simultaneously is

            FIND = (>Some String<)|("Some String")
            REPLACE = (?1>New String<)(?2"New String")
            SEARCH MODE = Regular Expression

            But that’s “annoying” because you have to repeat the Some String and New String in the FIND and REPLACE.

            There are some fancy tricks using capture groups, either named or numbered, and control-flow assertions, to make sure that things balance correctly, and it will only match .

            FIND = (?'startwrap'(?'angled'>)|(?'quoted'"))\KSome String(?'endwrap'(?=(?('quoted')")(?('angled')<)))
            REPLACE = New String
            SEARCH MODE = Regular expression

            But as you can see, the FIND becomes rather complicated to save the “expense” of having Some String and New String twice. (You could theoretically do it with numbered capture groups instead, but getting the counts right, especially as you edit to make a third pair like {Some String}, would cause problems, so I used named groups so there was no ambiguity in the future. I will leave the “numbered group” version as an exercise to the interested reader.)

            So that’s two ways. Which is best depends on which you understand, and whether it’s going to be expanded in the future and/or done often. The most important thing with regex is that you understand what it’s doing, so that you don’t mess up your data.

            If you don’t understand a “single regex version” but can get it done in two simple search-and-replace that you fully understand, then two simple is probably better for you. (If it’s something you will be doing often, you can record the two search-and-replace into a macro, so that you can just play that macro in the future.)

            @PeterJones, thank you very much for your advice!
            I look at the options you suggested and once again I am convinced that RegEx was definitely not created by people and not for people :):):)
            Way #1 (captured group) is absolutely clear to me. I myself thought that it was necessary to act somehow through the groups, but I could not understand how.

            And as you correctly noted - this way in terms of labor costs is not much more efficient than the method without RegEx. The old and new lines have to be written twice.

            The second way is also clear to me, but only in general terms. This option is a very good warm-up for the mind. And I will definitely save this option for the future.

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