• Login
Community
  • Login

RegEx, exclude search in any brackets

Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
11 Posts 4 Posters 1.5k 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.
  • L
    litos81
    last edited by Oct 20, 2020, 12:43 PM

    Perhaps any of these expressions that use a negative lookahead so that the selected comma is not one eventually followed by any amount of characters except an opening bracket and finally a closing bracket could work?
    Find what: ,(?![^{]*}) or ,(?![^\(]*\))
    Replace: ,\r\n

    A 1 Reply Last reply Oct 20, 2020, 3:46 PM Reply Quote 4
    • A
      andrecool-68 @litos81
      last edited by Oct 20, 2020, 3:46 PM

      @litos81
      It is absolutely true that not need to touch anything inside any parentheses.

      A 1 Reply Last reply Oct 20, 2020, 5:01 PM Reply Quote 0
      • A
        Alan Kilborn @andrecool-68
        last edited by Oct 20, 2020, 5:01 PM

        @andrecool-68 said in RegEx, exclude search in any brackets:

        It is absolutely true that not need to touch anything inside any parentheses.

        So then you have your solution then, or do you need more help with this?

        1 Reply Last reply Reply Quote 0
        • G
          guy038
          last edited by guy038 Oct 20, 2020, 7:53 PM Oct 20, 2020, 7:40 PM

          Hello, @andrecool-68, @litos81, @alan-kilborn and All,

          Glad to help you, this time ! I’m taking up the @litos81’s idea a little bit but, instead of using a negative look-ahead, I chose a positive one which ensures that all the commas searched are always followed with a complete multi-lines block {.......}.

          Two other tricks :

          • If a space char follows the comma, it is deleted when moving to next line.

          • A negative look-ahead (?!\R) prevent from extra-blank lines if, by mistake, you decide to run, again, this S/R on the replacement text itself !

          Thus, the regex S/R :

          SEARCH ,\x20?(?!\R)(?=[^{}]*\{[^{}]+\})

          REPLACE ,\r\n

          does change this text :

          .layoutBlock_noborder_KYBnB5Up, .layoutBlock_39IwNSU_,.layoutBlock_noborder_KYBnB56Up{
              background-color:#fff;
              border-top:1px solid rgba(0,0,0,.12);
              border-right:1px solid rgba(0,0,0,.12);
              border-left:1px solid rgba(0,0,0,.12)
          }
          
          
          .layoutBlock_noborder_KYBnB5Up, .layoutBlock_39IwNSU_,.layoutBlock_noborder_KYBnB56Up{
              background-color:#fff;
              border-top:1px solid rgba(0,0,0,.12);
              border-right:1px solid rgba(0,0,0,.12);
              border-left:1px solid rgba(0,0,0,.12)
          }
          

          as :

          .layoutBlock_noborder_KYBnB5Up,
          .layoutBlock_39IwNSU_,
          .layoutBlock_noborder_KYBnB56Up{
              background-color:#fff;
              border-top:1px solid rgba(0,0,0,.12);
              border-right:1px solid rgba(0,0,0,.12);
              border-left:1px solid rgba(0,0,0,.12)
          }
          
          
          .layoutBlock_noborder_KYBnB5Up,
          .layoutBlock_39IwNSU_,
          .layoutBlock_noborder_KYBnB56Up{
              background-color:#fff;
              border-top:1px solid rgba(0,0,0,.12);
              border-right:1px solid rgba(0,0,0,.12);
              border-left:1px solid rgba(0,0,0,.12)
          }
          
          

          Best Regards,

          guy038

          1 Reply Last reply Reply Quote 2
          • A
            andrecool-68
            last edited by Oct 21, 2020, 6:57 AM

            Hi all! @litos81 @guy038 @Alan-Kilborn

            The example of your regular expressions works, but if there is such a structure in the code, changes will be made (although everything is in general brackets):

            @-webkit-keyframes shake {
                0%,to {
                    transform: translateZ(0)
                }
            
                15%,25%,35%,45%,5%,55%,65%,75%,85%,95% {
                    transform: translate3d(-20px,0,0)
                }
            
                10%,20%,30%,40%,50%,60%,70%,80%,90% {
                    transform: translate3d(20px,0,0)
                }
            }
            

            This is an example of my macro that does the formatting of compressed CSS code.

            <Macro name="CSS sort" Ctrl="no" Alt="no" Shift="no" Key="0">
            	<Action type="3" message="1700" wParam="0" lParam="0" sParam="" />
            	<Action type="3" message="1601" wParam="0" lParam="0" sParam="/*" />
            	<Action type="3" message="1625" wParam="0" lParam="1" sParam="" />
            	<Action type="3" message="1602" wParam="0" lParam="0" sParam="\n\n/*" />
            	<Action type="3" message="1702" wParam="0" lParam="1792" sParam="" />
            	<Action type="3" message="1701" wParam="0" lParam="1609" sParam="" />
            	<Action type="3" message="1700" wParam="0" lParam="0" sParam="" />
            	<Action type="3" message="1601" wParam="0" lParam="0" sParam="*/" />
            	<Action type="3" message="1625" wParam="0" lParam="1" sParam="" />
            	<Action type="3" message="1602" wParam="0" lParam="0" sParam="*/\n\n" />
            	<Action type="3" message="1702" wParam="0" lParam="1792" sParam="" />
            	<Action type="3" message="1701" wParam="0" lParam="1609" sParam="" />
            	<Action type="3" message="1700" wParam="0" lParam="0" sParam="" />
            	<Action type="3" message="1601" wParam="0" lParam="0" sParam="{" />
            	<Action type="3" message="1625" wParam="0" lParam="1" sParam="" />
            	<Action type="3" message="1602" wParam="0" lParam="0" sParam="{\n\t" />
            	<Action type="3" message="1702" wParam="0" lParam="1792" sParam="" />
            	<Action type="3" message="1701" wParam="0" lParam="1609" sParam="" />
            	<Action type="3" message="1700" wParam="0" lParam="0" sParam="" />
            	<Action type="3" message="1601" wParam="0" lParam="0" sParam="}" />
            	<Action type="3" message="1625" wParam="0" lParam="1" sParam="" />
            	<Action type="3" message="1602" wParam="0" lParam="0" sParam="\n\t}\n\n" />
            	<Action type="3" message="1702" wParam="0" lParam="1792" sParam="" />
            	<Action type="3" message="1701" wParam="0" lParam="1609" sParam="" />
            	<Action type="3" message="1700" wParam="0" lParam="0" sParam="" />
            	<Action type="3" message="1601" wParam="0" lParam="0" sParam=";" />
            	<Action type="3" message="1625" wParam="0" lParam="1" sParam="" />
            	<Action type="3" message="1602" wParam="0" lParam="0" sParam=";\n\t" />
            	<Action type="3" message="1702" wParam="0" lParam="1792" sParam="" />
            	<Action type="3" message="1701" wParam="0" lParam="1609" sParam="" />
            </Macro>
            
            1 Reply Last reply Reply Quote 0
            • A
              andrecool-68
              last edited by Oct 21, 2020, 7:06 AM

              To my macro, I wanted to add an option for formatting headers that are separated by commas, roughly speaking, this will be the second macro.
              For notepad++ there is no Tidy-CSS plugin, and you have to invent a curve bicycle)).

              1 Reply Last reply Reply Quote 0
              • A
                andrecool-68
                last edited by Oct 21, 2020, 8:22 AM

                This regex should only work if:

                The beginning of a line that does not contain a space or tab at the beginning, but this line always ends with a curly brace.

                1 Reply Last reply Reply Quote 0
                • G
                  guy038
                  last edited by guy038 Oct 21, 2020, 5:09 PM Oct 21, 2020, 4:47 PM

                  Hi, @andrecool-68, @litos81, @alan-kilborn and All,

                  Ah… OK ! In this case, we’ll need to use recursive regexes in order to find out, first, the greatest well-balanced block of nested blocks as, for instance, the string {....{.......{..{......{...}.........}..}....}...}


                  So, before dealing with the comma character, I would use this regex S/R, written in free-spacing mode, in order to surround the outer block with the two control characters STX and ETX :

                  SEARCH (?x) \{ (?: [^{}]++ | (?R) )* \}

                  REPLACE \x02$0\x03

                  Note that (?R) ( or (?0) ) is a recursive call to the whole match itself ( $0 ) and that [^{}]++ is an atomic range of allowed characters in a single {.....} block

                  So, given this example, below :

                  @-webkit-keyframes ,shake, bla,blah, waooohh{
                      0%,to {
                          transform: translateZ(0)
                      }
                  
                      15%,25%,35%,45%,5%,55%,65%,75%,85%,95% {
                          transform: translate3d(-20px,0,0)
                      }
                  
                      10%,20%,30%,40%,50%,60%,70%,80%,90% {
                          transform: translate3d(20px,0,0)
                      }
                  }
                  
                  @-webkit-keyframes ,shake, bla,blah, waooohh{
                      0%,to {
                          transform: translateZ(0)
                      }
                  
                      15%,25%,35%,45%,5%,55%,65%,75%,85%,95% {
                          transform: translate3d(-20px,0,0)
                      }
                  
                      10%,20%,30%,40%,50%,60%,70%,80%,90% {
                          transform: translate3d(20px,0,0)
                      }
                  
                      15%,25%,35%,45%,5%,55%,65%,75%,85%,95% {
                          transform: translate3d(-20px,0,0)
                      }
                  }
                  

                  we get :

                  @-webkit-keyframes ,shake, bla,blah, waooohh{
                      0%,to {
                          transform: translateZ(0)
                      }
                  
                      15%,25%,35%,45%,5%,55%,65%,75%,85%,95% {
                          transform: translate3d(-20px,0,0)
                      }
                  
                      10%,20%,30%,40%,50%,60%,70%,80%,90% {
                          transform: translate3d(20px,0,0)
                      }
                  }
                  
                  @-webkit-keyframes ,shake, bla,blah, waooohh{
                      0%,to {
                          transform: translateZ(0)
                      }
                  
                      15%,25%,35%,45%,5%,55%,65%,75%,85%,95% {
                          transform: translate3d(-20px,0,0)
                      }
                  
                      10%,20%,30%,40%,50%,60%,70%,80%,90% {
                          transform: translate3d(20px,0,0)
                      }
                  
                      15%,25%,35%,45%,5%,55%,65%,75%,85%,95% {
                          transform: translate3d(-20px,0,0)
                      }
                  }
                  

                  However, note that the STX and ETX control chars are not displayed on our forum, although really present in text !


                  Secondly, if we assume that :

                  • The \x02 control character plays the role of the opening curly brace { in the regex of my previous post

                  • The \x03 control character plays the role of the ending curly brace } in the regex of my previous post

                  We just get the right regex S/R, which, in addition, deletes the STX and ETX control chars as well :

                  SEARCH (?x) (,) \x20? (?= [^\x02\x03]*? \x02 [^\x02\x03]+? \x03) | [\x02\x03]

                  REPLACE ?1,\r\n

                  And, @andrecool-68, you get your expected text :

                  @-webkit-keyframes ,
                  shake,
                  bla,
                  blah,
                  waooohh{
                      0%,to {
                          transform: translateZ(0)
                      }
                  
                      15%,25%,35%,45%,5%,55%,65%,75%,85%,95% {
                          transform: translate3d(-20px,0,0)
                      }
                  
                      10%,20%,30%,40%,50%,60%,70%,80%,90% {
                          transform: translate3d(20px,0,0)
                      }
                  }
                  
                  @-webkit-keyframes ,
                  shake,
                  bla,
                  blah,
                  waooohh{
                      0%,to {
                          transform: translateZ(0)
                      }
                  
                      15%,25%,35%,45%,5%,55%,65%,75%,85%,95% {
                          transform: translate3d(-20px,0,0)
                      }
                  
                      10%,20%,30%,40%,50%,60%,70%,80%,90% {
                          transform: translate3d(20px,0,0)
                      }
                  
                      15%,25%,35%,45%,5%,55%,65%,75%,85%,95% {
                          transform: translate3d(-20px,0,0)
                      }
                  }
                  

                  Cheers,

                  guy038

                  1 Reply Last reply Reply Quote 3
                  • L
                    litos81
                    last edited by Oct 21, 2020, 5:40 PM

                    Hi,
                    I was also still intrigued by this ‘functionality’ and I came out with an expression that uses what the manual calls a “continuation Escape” \G which matches the end of the previous match.
                    So, based exclusively on a CSS example I think it could work… but it may also miss very intricate CSS rules as I admit this expression doesn’t take much care of nested blocks as @guy038 solution does:
                    Find what: ((?:^\S|\G)[^\{,]*,\x20?)(?=.*{)
                    Replace: $1\r\n
                    Basically it searchs for any line that starts by a non-white character and selects any portion of text between the start or the previous match and a comma (and possible space) all the way until a { character.

                    1 Reply Last reply Reply Quote 3
                    • A
                      andrecool-68
                      last edited by Oct 21, 2020, 7:10 PM

                      @guy038 Thank you for help!
                      I combined my macro and your two regular expressions into one, now everything works correctly and beautifully! But if the file is large (e.g. 100mb) the macro works for about 30 seconds))).

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