Reputation: 45
I want to get the string between 2 words in a string. like so:
String s = "Play A ROCK song"
So I want to get the string between: A and song, which in this case is rock.
I tried this:
public static String subStringBetween(String text, String after, String before) {
String p1 = getWordsAfter(text, after);
String p2 = getWordsBefore(text, before);
Set<String> aSet = new HashSet<>(Arrays.asList(p1.split(" ")));
Set<String> bSet = new HashSet<>(Arrays.asList(p2.split(" ")));
Set<String> result = new HashSet<>(aSet);
result.retainAll( bSet);
String string = "";
for (String s : result) {
if (string == "") {
string = s;
}else{
string +=" " + s;
}
}
return string;
}
public static String getWordsAfter(String text, String word) {
String[] splt = text.split(word);
return splt[1];
}
public static String getWordsBefore(String text, String word) {
String[] splt = text.split(word);
return splt[0];
}
It works, but If the string between A and Song is more than one word, it works, but prints something weird, like if it was: Play a Nice Rock Song the return would be Rock Nice, not Nice Rock
Upvotes: 1
Views: 1500
Reputation: 1524
You can also try a little bit shorter code:
public static String subStringBetween(String text, String after, String before) {
Pattern pattern = Pattern.compile("(?<=\\s|^)"+after +"\\s(.*?)\\s+"+ before);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
return matcher.group(1);
}
return ""; //or null or whatever you need
}
Input: Play a Nice Rock Song
After: a
Before: Song
Output: Nice Rock
Input: play a rock song xxx
After: a
Before: song
Output: rock
Input: a Play Nice Rock Song
After: a
Before: Song
Output: Play Nice Rock
Input: aaaa bbbb a bbb aaa b aaaa bbb
After: a
Before: b
Output: bbb aaa
Upvotes: 1
Reputation: 106470
This is a very novel way of going about this, so I'll respect that and not suggest regular expressions (although that would be the more straightforward approach).
In this context, you've run into an issue: hash sets are not guaranteed to be in any specific order, and since you're iterating over them in a specific order, who knows what order those strings will come in?
The fix is actually very simple. Make use of the LinkedHashSet
class instead. This is guaranteed to preserve insertion order.
Do this for all of the sets you're using.
Set<String> aSet = new LinkedHashSet<>(Arrays.asList(p1.split(" ")));
Set<String> bSet = new LinkedHashSet<>(Arrays.asList(p2.split(" ")));
Set<String> result = new LinkedHashSet<>(aSet);
Then, the order will be what you expect when you invoke your method.
Upvotes: 2