1

I would like to split string into List on two possible delimeters "/" or "//". But what is more the delimeter should also be put into the same List. I can not do this with Splitter in Guava or java.util.Scanner.

Scanner s = new Scanner(str);
s.useDelimiter("//|/");
while (s.hasNext()) {
    System.out.println(s.delimiter());
    System.out.println(s.next());
}

s.delimiter() returns //|/. I want to get / or //.

Do you know any other library which can do this?

I wrote some code, and it works but it is not very nice solution:

public static ArrayList<String> processString(String s) {
    ArrayList<String> stringList = new ArrayList<String>();
    String word = "";
    for (int i = 0; i < s.length(); i++) {
        if (s.charAt(i) == '/' && i < s.length() && s.charAt(i + 1) == '/') {
            if (!word.equals(""))
                stringList.add(word);
            stringList.add("//");
            word = "";
            i++;
        } else if (s.charAt(i) == '/') {
            if (!word.equals(""))
                stringList.add(word);
            stringList.add("/");
            word = "";
        }else{
            word = word + String.valueOf(s.charAt(i));
        }
    }
    stringList.add(word);
    return stringList;
}

On "some/string//with/slash/or//two" returns List with some, /, string, //, with, /, slash, /, or, //, two

On "/some/string//with/slash/or//two" returns List with /, some, /, string, //, with, /, slash, /, or, //, two

On "//some/string//with/slash/or//two" returns List with //, some, /, string, //, with, /, slash, /, or, //, two

f4lco
  • 3,728
  • 5
  • 28
  • 53
LancerX
  • 1,211
  • 7
  • 23
  • 40
  • 1
    Perhaps this has the answer http://stackoverflow.com/questions/2206378/how-to-split-a-string-but-also-keep-the-delimiters – The Cat Oct 29 '12 at 17:36
  • Unfortunately this is not the same issue. In my case, the delimiter can be `/` or `//`. So this `System.out.println(Arrays.toString("a/b//c/d".split("((?<=//)|(?=//)|(?<=/)|(?=/))")));` doesn't work. – LancerX Oct 29 '12 at 20:01

2 Answers2

5

The useDelimiter method has a signature that takes a Pattern object, instead of a String.

You should use that one instead:

Scanner s = new Scanner(str);
s.useDelimiter(Pattern.compile("/{1,2}"));
while (s.hasNext()) {
    System.out.println(s.delimiter());
    System.out.println(s.next());
}

In order to capture the delimiter, you're going to need to change your approach.

Pattern p = new Pattern("(/{0,2})([^/]+)");
Matcher m = p.matcher(str);
while(m.find()) {
   String token     = m.group(2);
   String delimiter = m.group(1); // (preceding delimiter. may be null)
   /*
    * ...
    */
}
Dancrumb
  • 26,597
  • 10
  • 74
  • 130
  • `s.useDelimiter(Pattern.compile("/{1,2}"))` and `s.useDelimiter("//|/")` are doing the same. And I still can't see which delimiter was used. `s.delimiter()` returns `/{1,2}` – LancerX Oct 29 '12 at 17:47
0

This seems like a good candidate to use regular expressions. You can read more about Java regular expressions here.

Derek Hogue
  • 4,589
  • 1
  • 15
  • 27
user1700184
  • 1,611
  • 2
  • 16
  • 23