Home > Back-end >  How can I match all instances of MyClass where AnotherClass is an argument without using lookaheads/
How can I match all instances of MyClass where AnotherClass is an argument without using lookaheads/

Time:11-03

What I am trying to solve is how to match all instances of MyClass where AnotherClass is an argument. The biggest constraint I have is that I am doing this with go regex, so I dont have access to lookaheads/lookbehinds, and I also need to match without using a third party lib. But because the sample can be written in various ways, I am trying to match to match all possible cases. The end goal really is to get the inverse of the result, but for now, the focus is on matching first, and then use | to get the inverse.

So really the end goal is to match any cases where MyClass does not have AnotherClass as an argument. For example cases 0, 1, 4 etc.

regex 101

Here are some of the test cases

# case 0
return new MyClass(constructor, options, ...);

# case 1
var mc = new MyClass();
# case 2
var mc = new MyClass(new AnotherClass());
# case 3
var amc = new MyClass(options, new AnotherClass(), ...);

# case 4
MyClass mc = new MyClass(
  something
);

# case 5
MyClass mc = new MyClass(
  new AnotherClass()
);

# case 6
MyClass mc = new MyClass(
  options, new AnotherClass()
);

# case 7
var amc = new MyClass(new AnotherClass(), options, ...);

The regex I am using is (?s)(?:new\sMyClass\(new\sAnotherClass\(\).*?\)). Please do note that I am using the (?s) flag to indicate dot matches new line, as some of the cases can have new line. I am also wrapping this in a non capturing group as the end goal is to get the inverse of the matches.

The issue that I am running into is I can only match case #2 and #7. I do understand why that is as because I am not accounting for anything that might be after MyClass, but when I do a . ?, it it matching more than the actual match itself.

Happy to answer any clarifying questions if my question doesnt make sense.

CodePudding user response:

Semicolons never appear in the middle of a statement, so use [^;] instead of . to match multiple characters in the argument list.

This works with your test cases (the final .* is okay because we already can't span multiple statements due to the first [^;])

(?s)(?:new\sMyClass\([^;]*?new\sAnotherClass\(\).*?\))
  • Related