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.
    • andrecool-68A
      andrecool-68
      last edited by andrecool-68

      You need to find all the commas and after them make a line break, And how to exclude the search between any brackets?
      This is to create a macro to format a compressed CSS file.

      У нас есть это:

      .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)
      }
      

      That’s what we need to get:

      .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)
      }
      
      1 Reply Last reply Reply Quote 0
      • L
        litos81
        last edited by

        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

        andrecool-68A 1 Reply Last reply Reply Quote 4
        • andrecool-68A
          andrecool-68 @litos81
          last edited by

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

          Alan KilbornA 1 Reply Last reply Reply Quote 0
          • Alan KilbornA
            Alan Kilborn @andrecool-68
            last edited by

            @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
            • guy038G
              guy038
              last edited by guy038

              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
              • andrecool-68A
                andrecool-68
                last edited by

                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
                • andrecool-68A
                  andrecool-68
                  last edited by

                  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
                  • andrecool-68A
                    andrecool-68
                    last edited by

                    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
                    • guy038G
                      guy038
                      last edited by guy038

                      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

                        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
                        • andrecool-68A
                          andrecool-68
                          last edited by

                          @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
                          • First post
                            Last post
                          The Community of users of the Notepad++ text editor.
                          Powered by NodeBB | Contributors