分隔符的每第n个位置拆分,并保留字符。

huangapple go评论48阅读模式
英文:

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

问题

需要一个函数来将一个字符串更改为如下格式的字符串数组:

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

在这个示例中,分隔符是“,”并且每隔2个元素进行拆分。
有许多类似的在线函数可以实现这个功能,但它们都会删除分隔符。

英文:

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.

答案1

得分: 1

这应该可以正常工作。

String sample = "红色,绿色,蓝色,橙色,粉色,灰色,紫色";
ArrayList<String> output = new ArrayList<>();

Pattern firstPattern = Pattern.compile("[\\u4e00-\\u9fa5,\\s]*,[\\u4e00-\\u9fa5,\\s]*|");
Matcher firstMatcher = firstPattern.matcher(sample);
Pattern secondPattern = Pattern.compile("[\\u4e00-\\u9fa5,\\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:

红色, 绿色,
 蓝色, 橙色,
 粉色, 灰色,
 紫色
英文:

this should work fine.

    String sample = &quot;Red, Green, Blue, Orange, Pink, Gray, Purple&quot;;
    ArrayList&lt;String&gt; output = new ArrayList&lt;&gt;();

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

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

output:

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

答案2

得分: 1

这里有一个在线性时间复杂度 O(n) 内运行的简单解决方案:

分隔符的每第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;
}
英文:

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

分隔符的每第n个位置拆分,并保留字符。

where groupSize = 2

    public static ArrayList&lt;String&gt; splitPairs(String input, int groupSize) {
    String[] inputArray = input.split(&quot;,&quot;);
    ArrayList&lt;String&gt; result = new ArrayList&lt;&gt;();
    int index = 0;

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

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

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

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

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

    return result;
}

答案3

得分: 0

A not very good solution may help you.

First: 将字符串按','拆分为String[]

Second: 将String数组拆分为字符串数组的数组,每个小数组包含0、1或2个元素

Third: 合并小字符串数组。

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

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

答案4

得分: 0

以下是没有使用正则表达式的方法,使用了我在评论中提到的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;
}

希望对您有所帮助。

英文:

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 = &quot;Red, Green, Blue, Orange, Pink, Gray, Purple&quot;;
  final int n = 2;
  final char delim = &#39;,&#39;;
  nthSep(input, n, delim).stream().forEach(System.out::println);
}

private static LinkedList&lt;String&gt; nthSep(String input, int n, char delim) {
  LinkedList&lt;String&gt; res = new LinkedList&lt;&gt;();
  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 &lt; 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;
}

huangapple
  • 本文由 发表于 2020年7月28日 07:17:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/63124945.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定