0

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?

3
  • Define 'better'. Commented Feb 15, 2018 at 11:46
  • No it doesn't. It prints ffcc218c-985c-4ec8-82d7-751fdcac93f. Without the last character. Commented Feb 15, 2018 at 11:53
  • Why would you want to use 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. Commented Feb 15, 2018 at 12:36

3 Answers 3

3

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";
Sign up to request clarification or add additional context in comments.

2 Comments

Carefull that regex .* is greedy, so the first .* will consume as many "/" as possible. So it will basicly take the value just before the last "/". The initial code was usin the value after the first "/" instead. No difference here, since only 2 "/" are used. (after he consume the first one)
@AxelH Agreed - I had originally put a ? but decided to remove it to stick to the question and make the answer a bit simpler.
1

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

Comments

0

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.

4 Comments

The original question has a wrong character count. You must have relied on it, because you transferred the mistake to your answer.
@Gonen I: I didn't check that because the question was not about an error in the result. I think I fixed that now (but feel free to edit my answer if it is still wrong.
"How can I use java Pattern library to write better code?"
@AxelH: Since better is not yet defined in the question, I wrote this answer about how to improve performance in case of object-creation and speed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.