Sherin Sunny
Sherin Sunny

Reputation: 145

Generating regex to exclude a string in path

I'm trying to write a regex which includes all 'component.ts' files which start with 'src' but excludes those files which have 'debug' folder in its file path using

(src\/.*[^((?!debug).)*$]/*.component.ts)

I'm testing the following strings on regex101 tester:

src/abcd/debug/xtz/component/ddd/xyz.component.ts

src/abcd/arad/xtz/xyz.component.ts

Both these strings are giving a perfect match, even though the first one has 'debug' in its path. Where am I going wrong?

Upvotes: 5

Views: 13405

Answers (2)

The fourth bird
The fourth bird

Reputation: 163207

You are specifying a negative lookahead (?! in a character class [^((?!debug).)*$] which would then only match the characters inside the character class.

What you could do is move the negative lookahead to the beginning to assert that what follows is not /debug or /debug/:

^(?!.*\/debug\/)src\/.*component\.ts$

Explanation

  • ^ Assert the start of the line
  • (?!.*\/debug\/) Negative lookahead to assert that what follows is not /debug/
  • src Match literally
  • \/.*component\.ts Match a forward slash followed by any character zero or more times followed by .ts
  • $ Assert the end of the string

Note that to match the dot literally you have to escape it \. or else it would match any character.

Upvotes: 5

Aankhen
Aankhen

Reputation: 2272

Your regex matches:

  • src/
  • followed by zero or more non-newline characters
  • followed by one character that is not in the character class ((?!debug).)*$
  • followed by zero or more slashes
  • followed by a non-newline character
  • followed by component
  • followed by a non-newline character followed by ts.

In other words, the [^((?!debug).)*$], is not a lookbehind as you probably intended but rather a character class.

We can rephrase the desired match to see what we need:

  • src
  • followed by one or more path segments, each of which is not equal to debug
  • followed by the filename

Which gives us:

^src(?:/[^/]+(?<!debug))+/[^/]+\.component\.ts$

(Remember to escape the forward slashes if you’re using these in JavaScript.)

Try it on Regex101.

I added the ^ and $ because I assume you want the entire input to match. If you’re searching within a large string, you can remove those and instead change both instances of [^/] to [^\n/].

By the way, there’s no need to place the entire regex inside parentheses, as the first match will be the entire matched string in most languages.

Upvotes: 2

Related Questions