Java 在每第 n 个字符处拆分一个字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2297347/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Splitting a string at every n-th character
提问by Vijay Dev
In JavaScript this is how we can split a string at every 3-rd character
在 JavaScript 中,这就是我们如何在每 3 个字符处拆分字符串
"foobarspam".match(/.{1,3}/g)
I am trying to figure out how to do this in Java. Any pointers?
我想弄清楚如何在 Java 中做到这一点。任何指针?
采纳答案by Bart Kiers
You could do it like this:
你可以这样做:
String s = "1234567890";
System.out.println(java.util.Arrays.toString(s.split("(?<=\G...)")));
which produces:
它产生:
[123, 456, 789, 0]
The regex (?<=\G...)
matches an empty string that has the last match(\G
) followed by three characters(...
) beforeit ((?<= )
)
正则表达式(?<=\G...)
具有一个空字符串匹配的最后一场比赛(\G
),其次是三个字符(...
)之前它((?<= )
)
回答by Simon Nickerson
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
for (String part : getParts("foobarspam", 3)) {
System.out.println(part);
}
}
private static List<String> getParts(String string, int partitionSize) {
List<String> parts = new ArrayList<String>();
int len = string.length();
for (int i=0; i<len; i+=partitionSize)
{
parts.add(string.substring(i, Math.min(len, i + partitionSize)));
}
return parts;
}
}
回答by Kevin Bourrillion
Java does not provide very full-featured splitting utilities, so the Guava librariesdo:
Java 没有提供非常全功能的拆分实用程序,因此Guava 库可以:
Iterable<String> pieces = Splitter.fixedLength(3).split(string);
Check out the Javadoc for Splitter; it's very powerful.
回答by Frodo
As an addition to Bart Kiersanswer I want to add that it is possible instead of using the three dots ...
in the regex expression which are representing three characters you can write .{3}
which has the same meaning.
作为对Bart Kiers回答的补充,我想补充一点,可以不使用...
正则表达式中的三个点,这三个点代表您可以编写的.{3}
具有相同含义的三个字符。
Then the code would look like the following:
然后代码将如下所示:
String bitstream = "00101010001001010100101010100101010101001010100001010101010010101";
System.out.println(java.util.Arrays.toString(bitstream.split("(?<=\G.{3})")));
With this it would be easier to modify the string length and the creation of a function is now reasonable with a variable input string length. This could be done look like the following:
有了这个,修改字符串长度会更容易,并且现在使用可变输入字符串长度创建函数是合理的。这可以像下面这样完成:
public static String[] splitAfterNChars(String input, int splitLen){
return input.split(String.format("(?<=\G.{%1$d})", splitLen));
}
An example in IdeOne: http://ideone.com/rNlTj5
IdeOne 中的一个例子:http://ideone.com/rNlTj5
回答by Cardinal - Reinstate Monica
This a late answer, but I am putting it out there anyway for any new programmers to see:
这是一个迟到的答案,但无论如何我都会把它放在那里供任何新程序员看到:
If you do not want to use regular expressions, anddo not wish to rely on a third party library, you can use this method instead, which takes between 89920and 100113nanoseconds in a 2.80 GHz CPU(less than a millisecond). It's not as pretty as Simon Nickerson's example, but it works:
如果你不想使用正则表达式,并且不希望依靠第三方库,你可以用这个方法来代替,这需要之间 89920和100113纳秒在2.80 GHz的CPU(小于1ms)。它不像西蒙尼克森的例子那么漂亮,但它有效:
/**
* Divides the given string into substrings each consisting of the provided
* length(s).
*
* @param string
* the string to split.
* @param defaultLength
* the default length used for any extra substrings. If set to
* <code>0</code>, the last substring will start at the sum of
* <code>lengths</code> and end at the end of <code>string</code>.
* @param lengths
* the lengths of each substring in order. If any substring is not
* provided a length, it will use <code>defaultLength</code>.
* @return the array of strings computed by splitting this string into the given
* substring lengths.
*/
public static String[] divideString(String string, int defaultLength, int... lengths) {
java.util.ArrayList<String> parts = new java.util.ArrayList<String>();
if (lengths.length == 0) {
parts.add(string.substring(0, defaultLength));
string = string.substring(defaultLength);
while (string.length() > 0) {
if (string.length() < defaultLength) {
parts.add(string);
break;
}
parts.add(string.substring(0, defaultLength));
string = string.substring(defaultLength);
}
} else {
for (int i = 0, temp; i < lengths.length; i++) {
temp = lengths[i];
if (string.length() < temp) {
parts.add(string);
break;
}
parts.add(string.substring(0, temp));
string = string.substring(temp);
}
while (string.length() > 0) {
if (string.length() < defaultLength || defaultLength <= 0) {
parts.add(string);
break;
}
parts.add(string.substring(0, defaultLength));
string = string.substring(defaultLength);
}
}
return parts.toArray(new String[parts.size()]);
}
回答by Pankaj Singhal
Late Entry.
迟到。
Following is a succinct implementation using Java8 streams, a one liner:
以下是使用 Java8 流的简洁实现,一个单行:
String foobarspam = "foobarspam";
AtomicInteger splitCounter = new AtomicInteger(0);
Collection<String> splittedStrings = foobarspam
.chars()
.mapToObj(_char -> String.valueOf((char)_char))
.collect(Collectors.groupingBy(stringChar -> splitCounter.getAndIncrement() / 3
,Collectors.joining()))
.values();
Output:
输出:
[foo, bar, spa, m]
回答by Victor Truong
You can also split a string at every n-th character and put them each, in each index of a List :
您还可以在每个第 n 个字符处拆分一个字符串,并将它们每个放在 List 的每个索引中:
Here I made a list of Strings named Sequence :
在这里,我制作了一个名为 Sequence 的字符串列表:
List < String > Sequence
列表 <String> 序列
Then I'm basically splitting the String "KILOSO" by every 2 words. So 'KI' 'LO' 'SO' would be incorporate in separate index of the List called Sequence.
然后我基本上每 2 个单词将字符串“KILOSO”分开。因此,'KI' 'LO' 'SO' 将被合并到名为 Sequence 的列表的单独索引中。
String S = KILOSO
Sequence = Arrays.asList(S.split("(?<=\G..)"));
字符串 S = KILOSO
序列 = Arrays.asList(S.split("(?<=\G..)"));
So when I'm doing :
所以当我在做:
System.out.print(Sequence)
System.out.print(序列)
It should print :
它应该打印:
[KI, LO, SO]
[KI,LO,SO]
to verify I can write :
验证我可以写:
System.out.print(Sequence.get(1))
System.out.print(Sequence.get(1))
it will print :
它会打印:
LO
LO
回答by RobOhRob
I recently encountered this issue, and here is the solution I came up with
我最近遇到了这个问题,这是我想出的解决方案
final int LENGTH = 10;
String test = "Here is a very long description, it is going to be past 10";
Map<Integer,StringBuilder> stringBuilderMap = new HashMap<>();
for ( int i = 0; i < test.length(); i++ ) {
int position = i / LENGTH; // i<10 then 0, 10<=i<19 then 1, 20<=i<30 then 2, etc.
StringBuilder currentSb = stringBuilderMap.computeIfAbsent( position, pos -> new StringBuilder() ); // find sb, or create one if not present
currentSb.append( test.charAt( i ) ); // add the current char to our sb
}
List<String> comments = stringBuilderMap.entrySet().stream()
.sorted( Comparator.comparing( Map.Entry::getKey ) )
.map( entrySet -> entrySet.getValue().toString() )
.collect( Collectors.toList() );
//done
// here you can see the data
comments.forEach( cmt -> System.out.println( String.format( "'%s' ... length= %d", cmt, cmt.length() ) ) );
// PRINTS:
// 'Here is a ' ... length= 10
// 'very long ' ... length= 10
// 'descriptio' ... length= 10
// 'n, it is g' ... length= 10
// 'oing to be' ... length= 10
// ' past 10' ... length= 8
// make sure they are equal
String joinedString = String.join( "", comments );
System.out.println( "\nOriginal strings are equal " + joinedString.equals( test ) );
// PRINTS: Original strings are equal true
回答by vishal
Using plain java:
使用普通的java:
String s = "1234567890";
List<String> list = new Scanner(s).findAll("...").map(MatchResult::group).collect(Collectors.toList());
System.out.printf("%s%n", list);
Produces the output:
产生输出:
[123, 456, 789]
[123, 456, 789]
Note that this discards leftover characters (0 in this case).
请注意,这会丢弃剩余的字符(在本例中为 0)。