javascriptregexruby-hash

Js regex allow optional line break and space indentation


Some relative posts:


let s = `
%nav.cf
  %ul.cf
    %li
      %a{
        :href => "#"
      } Item 1
    %li
      %a{href => "#"} Item 2
    %li
      %a{:href => "#"} Item 2
    %li
      %a{:href => "#"} Item 3

  %a{:href => "#", :id => "openup"} MENU

%h1 Basic Responsive Menu
%p Playing around and learning HAML + SCSS - Basic Responsive Menu.
`;

s.replace(/\{?[\r\n]+.*\=\>(.*)\}/g, cd=>{
  console.log(cd);
});

/*
      %a{href => "#"}

      %a{:href => "#"}

      %a{:href => "#"}


  %a{:href => "#", :id => "openup"}
*/

s.replace(/\{?[\r\n]+.*\=\>(.*)[\s]+\}/g, cd=>{
  console.log(cd);
});
/*
{
        :href => "#"
      }
*/

I am writing an adopter for a template engine, basically I need to extract all the hash insides {} that must have a =>.

The expected result are all the commented values above. which the code either returns first or the second.

{
        :href => "#"
      }
%a{href => "#"}
%a{:href => "#"}
%a{:href => "#"}
 %a{:href => "#", :id => "openup"}

please have a look at the second expression, where I try to allow the optional line break and spaces indentation, I wonder why it gets rid of the unescaped hashes returned before.


Solution

  • You don't need to use replace. Just use this regex for matching in MULTILINE mode

    ^[^{}\n]*{(?=[^}#]*#)[^}]*=>[^}]*}
    

    RegEx Demo

    Code:

    let s = `
    %nav.cf
      %ul.cf
        %li
          %a{
            :href => "#"
          } Item 1
        %li
          %a{href => "#"} Item 2
        %li
          %a{:href => "#"} Item 2
        %li
          %a{:href => "#"} Item 3
    
      %a{:href => "#", :id => "openup"} MENU
    
    %h1 Basic Responsive Menu
    %p Playing around and learning HAML + SCSS - Basic Responsive Menu.`;
    
    console.log( s.match(/^[^{}\n]*{(?=[^}#]*#)[^}]*=>[^}]*}/gm) );

    RegEx Details: