Derek
Derek

Reputation: 11915

Nested Lookarounds in java regex

I have a pattern that uses lookarounds to ensure that the captured string is between two other strings

so in other words for the subject string

xxxcabyyy

my regex looks like

String myregex = ((?<=xxx)cab(?=[y]+))

so I want to use this regex more than once, because I may be looking for something else like

(test string) xxxcabyyy

I want a regex that is like

"\(test string\)(?=" + myregex + ")"

to say find "(test string)" that comes before whatever my regex matched.

This doesnt seem to work exactly right and i think its beacuse I have lookarounds in my regex that I am now embedding in the lookforward...what can I do to correct this situation?

Upvotes: 0

Views: 251

Answers (3)

mathematical.coffee
mathematical.coffee

Reputation: 56905

If you want a solution with the lookarounds in other lookarounds, you can do

\(test string\)(?=.*?((?<=xxx)cab(?=[y]+)))

or if it's (test string) followed by the xxxcabyyy and just spaces in between that you're after:

\(test string\)(?= *((?<=xxx)cab(?=[y]+)))

This is because at the point at which you match (test string), there are still characters to go before you hit the xxxcabyyy, and you'll have to include them in your lookahead.

Upvotes: 0

Alan Moore
Alan Moore

Reputation: 75222

It's okay to put lookarounds inside other lookarounds, but I don't see why you need to. In fact, I don't see any need for lookarounds period. Won't this work?

"\\(test string\\)\s*xxx(cab)y+"

Assuming it's the cab part you're interested in, you can extract it via Matcher#group(1).

Upvotes: 1

Dawood
Dawood

Reputation: 5306

Your guess is right - that won't work because you've already specified the lookbehind and lookahead constructs in your string myregex. One way to solve this problem is to hold separate strings for what you want for the lookbehind and lookahead constructs and use them to build the final regex string just before you need to do the matching. For example, you could write a method such as the following that will return a regex string given the lookbehind and lookahead constructs and what to match between them:

public static String lookaroundRegex(String behind, String match, String ahead) {
    return "((?<=" + behind + ")" + match + "(?=" + ahead + "))";
}

You could then use it as follows:

String behind = "xxx";
String ahead = "[y]+";
String match = "cab";

// For the first case:
Pattern regexPattern1 = Pattern.compile(lookaroundRegex(behind, match, ahead));

// For the second case:
String behind2 = "\\(test string\\) " + behind;
Pattern regexPattern2 = Pattern.compile(lookaroundRegex(behind2, match, ahead));

Upvotes: 0

Related Questions