regex to use negative look far behind along with positive look behind?

75 Views Asked by At

I need it to select only value which has :this in line but not include which are under comment section (/* */)

I have tried this one which works and give 3 results but it is incorrect as it select the last one which is in comment

const str = `
    :this { 
      display: grid; 
    }

    p { color: red}

    :this { this is also okay to capture  }
    /* but do not capture this :this { } , so how to look far behind here */
`;

const pattren = '(?<=:)\\bthis\\b\\s*(?={)';
const rx = new RegExp(pattren, 'gmd');
const matches = str.matchAll(rx);
console.log([...matches]);

Trial 1:

look far behind that is there * in the same line but it does not work and gives 0 result

const pattern = '(?<!/*)(?<=:)\\bthis\\b\\s*(?={)'; 
3

There are 3 best solutions below

0
Unmitigated On BEST ANSWER

You can use (?<!/\*.*) to look for /* followed by zero or more characters.

const str = `
       :this { 
          display: grid; 
        }

        p { color: red}

         :this { this is also okay to capture  }
        /* but do not capture this :this { } , so how to look far behind here */
    `;

const re = /(?<!\/\*.*)(?<=:)\bthis\b\s*(?={)/gmd;
const matches = str.matchAll(re);
console.log([...matches]);

0
Peter Seliger On

I doubt there is a way achieving what the OP is wishing for with a positive lookbehind but a negative lookbehind like ...

/(?<!\/\*.*?):this\s*\{[^}]+\}/g

... which gets explained at its playground page does the job.

// see ... [https://regex101.com/r/0p8Uw2/1]
const regXExtractUncommentedThisRule = /(?<!\/\*.*?):this\s*\{[^}]+\}/g;

const sampleData = `
  :this { 
    display: grid; 
  }

  p { color: red}

  :this { this is also okay to capture }
  /* but do not capture this :this { } , so how to look far behind here */
  :this { 
    display: grid; 
  }

  p { color: red}

  :this { this is also okay to capture }
  /* but do not capture this :this { } , so how to look far behind here */`;

console.log(
  sampleData.match(regXExtractUncommentedThisRule)
);

1
trincot On

I would match the comment block, so it is out of the way. With capture groups you can then identify what you want to keep, and throw away the matches that don't have anything in the capture group.

In this snippet the output has the start-end indices of the matches:

const str = `
    :this { 
      display: grid; 
    }

    p { color: red}

    :this { this is also okay to capture  }
    /* but do not capture this :this { } , so how to look far behind here */
`;

const rx = /\/\*.*?\*\/|:(this\b\s*)\{/gsd;
const matches = Array.from(str.matchAll(rx), m => m.indices?.[1]).filter(Boolean);
console.log(matches);