user1184100
user1184100

Reputation: 6894

How to extract string between two strings using java Pattern

I have a string /subscription/ffcc218c-985c-4ec8-82d7-751fdcac93f0/subscribe from which I want to extract the middle string /subscription/<....>/subscribe. I have written the below code to get the string

String subscriber = subscriberDestination.substring(1);
int startPos = subscriber.indexOf("/") + 2;
int destPos = startPos + subscriber.substring(startPos + 2).indexOf("/");
return subscriberDestination.substring(startPos, destPos + 2);

Gives back ffcc218c-985c-4ec8-82d7-751fdcac93f0

How can I use java Pattern library to write better code?

Upvotes: 0

Views: 119

Answers (3)

Oleg Cherednik
Oleg Cherednik

Reputation: 18255

5c from me. I recommend to use Pattern for extracting substring with known format:

public final class Foo {
    private static final Pattern PATTERN = Pattern.compile(".*subscription\\/(?<uuid>[\\w-]+)\\/subscribe");

    public static String getUuid(String url) {
        Matcher matcher = PATTERN.matcher(url);
        return matcher.matches() ? matcher.group("uuid") : null;
    }
}

RegEx Demo

Upvotes: 1

MrSmith42
MrSmith42

Reputation: 10161

Performance can be improved by:

  1. not creating a substrings.
  2. Also indexOf(..) with a char should be faster than with String

    final int startPos = subscriberDestination.indexOf('/',1) + 1 ;
    final int destPos = subscriberDestination.indexOf('/',startPos+1);
    return subscriberDestination.substring(startPos, destPos );
    

About useing the java Pattern library:
Do you expect any performance gain? I doubt you'll get some by using java Pattern library. But I recommend to profile it to be absolute sure about it.

Upvotes: 0

assylias
assylias

Reputation: 328775

If you want to use a regular expression, a simple way would be:

return subscriber.replaceAll("/.*/([^/]*)/.*", "$1");
  • /.*/ is for the /subscription/ bit
  • ([^/]*) a capturing group that matches all characters until the next /
  • /.* is for the /subscribe bit

And the second argument of replaceAll says that we want to keep the first group.

You can use a Pattern to improve efficiency by compiling the expression:

Pattern p = Pattern.compile("/.*/([^/]*)/.*"); ///store it outside the method to reuse it

Matcher m = p.matcher(subscriber);
if (m.find()) return m.group(1);
else return "not found";

Upvotes: 3

Related Questions