【问题标题】:Splitting at every n-th separator, and keeping the character在每个第 n 个分隔符处拆分,并保留字符
【发布时间】:2020-07-27 23:17:17
【问题描述】:

我需要一个函数来改变这样的字符串:

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

变成这样的字符串[]:

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

在此示例中,字符为, ,并且每隔 2 次拆分一次。 网上有很多和这个类似的功能,但是都去掉了字符。

【问题讨论】:

  • 可以反复使用String的indexOf(int ch, int fromIndex)来查找第n个分隔符的索引。
  • 那究竟是怎么做到的呢?我无法绕过它。
  • 使用整数从左到右遍历输入字符串以跟踪您当前的位置。使用 indexOf 函数前进到下一个逗号字符。然后每隔一个逗号添加一个换行符。当您到达输入字符串的末尾并且有奇数个单词时,有一种特殊情况。

标签: java string list split


【解决方案1】:

这应该可以正常工作。

    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));

输出:

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

【讨论】:

    【解决方案2】:

    这是一个在线性时间 O(n) 内工作的简单解决方案

    其中 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;
    }
    

    【讨论】:

    • 如果你有一个偶数,最后一个(例如,如果我们删除紫色)将保留逗号。
    【解决方案3】:

    一个不太好的解决方案可能会对您有所帮助。

    首先:将字符串以','分割成String[]

    第二次:将字符串数组拆分为字符串数组,每个小数组有0,1或2个元素

    第三:加入小字符串数组。

    使用 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);
    }
    

    【讨论】:

      【解决方案4】:

      这是一种没有正则表达式的方法,使用我在评论中提到的indexOf 方法。它有点老派,所有的事情都是手动完成的,基本上只是使用indexOfsubstring,这使它满足了您“保持角色”的要求。

      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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-17
        相关资源
        最近更新 更多