简体   繁体   中英

Splitting at every n-th separator, and keeping the character

I need a function to change a String like this:

Red, Green, Blue, Orange, Pink, Gray, Purple

Into a String[] like this:

Red, Green,
Blue, Orange,
Pink, Gray,
Purple

In this example the character is , and splitting it every 2nd. There are many similar functions online to this one, but they all remove the character.

this should work fine.

    String sample = "Red, Green, Blue, Orange, Pink, Gray, Purple";
    ArrayList<String> output = new ArrayList<>();

    Pattern firstPattern = Pattern.compile("[a-zA-Z-\\s]*,[a-zA-Z-\\s]*,|[a-zA-Z-\\s]*,[a-zA-Z-\\s]*");
    Matcher firstMatcher = firstPattern.matcher(sample);
    Pattern secondPattern = Pattern.compile("[a-zA-Z-\\s]*$");
    Matcher secondMatcher = secondPattern.matcher(sample);

    while (firstMatcher.find()) {
        output.add(firstMatcher.group());
    }
    if ((output.size() * 2) < sample.split(",").length)
        if (secondMatcher.find())
            output.add(secondMatcher.group(0));

output:

Red, Green,
 Blue, Orange,
 Pink, Gray,
 Purple

here is a simple solution that works in linear time O(n)

在此处输入图像描述

where groupSize = 2

    public static ArrayList<String> splitPairs(String input, int groupSize) {
    String[] inputArray = input.split(",");
    ArrayList<String> result = new ArrayList<>();
    int index = 0;

    while (index < inputArray.length) {
        StringBuilder newItem = new StringBuilder();

        for (int i = 0; i < groupSize && index < inputArray.length; i++, index++) {
            if (i != 0)
                newItem.append(", ");

            newItem.append(inputArray[index].trim());

            if (i == groupSize - 1) {
                newItem.append(",");
            }
        }

        if (newItem.length() > 0) {
            result.add(newItem.toString());
        }
    }

    return result;
}

A not very good solution may help you.

First :split the string by ',' into String[]

Second :split String array into array of string array and every small array have 0,1 or 2 elements

Third :join the small string array.

A solution use google guava:

String input = "Red, Green, Blue, Orange, Pink, Gray, Purple";
List<List<String>> lists = Lists.partition(Arrays.asList(input.split(",")),2);
String[] outputs = new String[lists.size()];
lists.stream().map(strings -> String.join(", ", strings)).map(String::trim)
    .collect(Collectors.toList()).toArray(outputs);
for (String output: outputs) {
    System.out.println(output);
}

Here is an approach withouth regex, using the indexOf method that i mentioned in the comment. It's a little oldschool and does all the things manually, essentially just using indexOf and substring , which makes it fulfill your "keeping the character" requirement.

public static void main(String[] args) {
  String input = "Red, Green, Blue, Orange, Pink, Gray, Purple";
  final int n = 2;
  final char delim = ',';
  nthSep(input, n, delim).stream().forEach(System.out::println);
}

private static LinkedList<String> nthSep(String input, int n, char delim) {
  LinkedList<String> res = new LinkedList<>();
  int startsplit = 0;
  int delimcount = 0;
  int curInd = 0;
  //repeat until no separator is found
  while (true) {
    //remember the index of the current split part
    startsplit = curInd;
    delimcount = 0;
    //find the separator n times
    while (delimcount < n) {
      curInd = input.indexOf(delim, curInd+1);
      if (curInd == -1) {
        break;
      }
      delimcount++;
    }

    if(curInd != -1){
      //add a result to the list, then move on with the next split part
      res.add(input.substring(startsplit, curInd+1));
      curInd++;
    } else {
      //so further separator is found, add the whole remaining input
      res.add(input.substring(startsplit));
      break;
    }
  }
  return res;
}

Try this.

Pattern TWO_WORDS = Pattern.compile("[^,\\s]+(,\\s*[^,\\s]+)?(,\\s*)?");
String input = "Red, Green, Blue, Orange, Pink, Gray, Purple";
String[] result = TWO_WORDS.matcher(input).results()
    .map(m -> m.group())
    .toArray(String[]::new);
for (String s : result)
    System.out.println("#" + s + "#");

output

#Red, Green, #
#Blue, Orange, #
#Pink, Gray, #
#Purple#

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM