Home > Software engineering >  Get substring between "first two" occurrences of a character
Get substring between "first two" occurrences of a character

Time:10-17

I have a String:

 String thestra = "/aaa/bbb/ccc/ddd/eee";

Every time, in my situation, for this Sting, a minimum of two slashes will be present without fail.

And I am getting the /aaa/ like below, which is the subString between "FIRST TWO occurrences" of the char / in the String.

 System.out.println("/"   thestra.split("\\/")[1]   "/");

It solves my purpose but I am wondering if there is any other elegant and cleaner alternative to this?

Please notice that I need both slashes (leading and trailing) around aaa. i.e. /aaa/

CodePudding user response:

You can use indexOf, which accepts a second argument for an index to start searching from:

int start = thestra.indexOf("/");
int end = thestra.indexOf("/", start   1)   1;
System.out.println(thestra.substring(start, end));

Whether or not it's more elegant is a matter of opinion, but at least it doesn't find every / in the string or create an unnecessary array.

CodePudding user response:

Scanner::findInLine returning the first match of the pattern may be used:

String thestra = "/aaa/bbb/ccc/ddd/eee";
System.out.println(new Scanner(thestra).findInLine("/[^/]*/"));

Output:

/aaa/

CodePudding user response:

Use Pattern and Matcher from java.util.regex.

Pattern pattern = Pattern.compile("/.*?/");
Matcher matcher = pattern.matcher(str);
if (matcher.find()) { 
    String match = matcher.group(0);  // output
}

CodePudding user response:

Every time, in my situation, for this Sting, minimum two slashes will be present

if that is guaranteed, split at each / keeping those delimeters and take the first three substrings.

String str = String.format("%s%s%s",(thestra.split("((?<=\\/)|(?=\\/))")));

CodePudding user response:

One of the many ways can be replacing the string with group#1 of the regex, [^/]*(/[^/].*?/).* as shown below:

public class Main {
    public static void main(String[] args) {
        String thestra = "/aaa/bbb/ccc/ddd/eee";
        String result = thestra.replaceAll("[^/]*(/[^/].*?/).*", "$1");
        System.out.println(result);
    }
}

Output:

/aaa/

Explanation of the regex:

  • [^/]* : Not the character, /, any number of times
  • ( : Start of group#1
    • / : The character, /
    • [^/]: Not the character, /
    • .*?: Any character any number of times (lazy match)
    • / : The character, /
  • ) : End of group#1
  • .* : Any character any number of times

Updated the answer as per the following valuable suggestion from Holger:

Note that to the Java regex engine, the / has no special meaning, so there is no need for escaping here. Further, since you’re only expecting a single match (the .* at the end ensures this), replaceFirst would be more idiomatic. And since there was no statement about the first / being always at the beginning of the string, prepending the pattern with either , .*? or [^/]*, would be a good idea.

CodePudding user response:

Pattern.compile("/.*?/")
            .matcher(thestra)
            .results()
            .map(MatchResult::group)
            .findFirst().ifPresent(System.out::println);

You can test this variant :)

With best regards, Fr0z3Nn

CodePudding user response:

You could also match the leading forward slash, then use a negated character class [^/]* to optionally match any character except / and then match the trailing forward slash.

String thestra = "/aaa/bbb/ccc/ddd/eee";
Pattern pattern = Pattern.compile("/[^/]*/");
Matcher matcher = pattern.matcher(thestra);

if (matcher.find()) {
    System.out.println(matcher.group());
}

Output

/aaa/
  • Related