In JavaScript können wir so eine Zeichenfolge bei jedem dritten Zeichen teilen
"foobarspam".match(/.{1,3}/g)
Ich versuche herauszufinden, wie das in Java geht. Irgendwelche Hinweise?
In JavaScript können wir so eine Zeichenfolge bei jedem dritten Zeichen teilen
"foobarspam".match(/.{1,3}/g)
Ich versuche herauszufinden, wie das in Java geht. Irgendwelche Hinweise?
Antworten:
Sie könnten es so machen:
String s = "1234567890";
System.out.println(java.util.Arrays.toString(s.split("(?<=\\G...)")));
welches produziert:
[123, 456, 789, 0]
Der reguläre Ausdruck (?<=\G...)
entspricht einer leeren Zeichenfolge mit der letzten Übereinstimmung ( \G
), gefolgt von drei Zeichen ( ...
) davor ( (?<= )
)
\G
und Python wird nicht in einen regulären Ausdruck aufgeteilt, der null Zeichen entspricht. Aber wenn Java wie jede andere Sprache eine Methode zum Abrufen aller Übereinstimmungen hätte, hätten Sie diesen Trick nicht erst erfinden müssen, @Bart. ;)
[123, 4567890]
als Ergebnis :(
Java bietet keine voll funktionsfähigen Aufteilungsdienstprogramme, daher tun die Guava-Bibliotheken Folgendes:
Iterable<String> pieces = Splitter.fixedLength(3).split(string);
Schauen Sie sich das Javadoc für Splitter an . es ist sehr mächtig.
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;
}
}
substring
Methode ist tatsächlich intelligent genug, um die übergeordneten Zeichenfolgen char[]
für die Daten zu verwenden. Weitere Informationen finden Sie in dieser Antwort .
Als Ergänzung zu Bart Kiers Antwort möchte ich hinzufügen, dass es möglich ist, anstatt die drei Punkte ...
im regulären Ausdruck zu verwenden, die drei Zeichen darstellen, die Sie schreiben können .{3}
und die dieselbe Bedeutung haben.
Dann würde der Code wie folgt aussehen:
String bitstream = "00101010001001010100101010100101010101001010100001010101010010101";
System.out.println(java.util.Arrays.toString(bitstream.split("(?<=\\G.{3})")));
Damit wäre es einfacher, die Zeichenfolgenlänge zu ändern, und die Erstellung einer Funktion ist jetzt mit einer variablen Eingabezeichenfolgenlänge sinnvoll. Dies könnte folgendermaßen aussehen:
public static String[] splitAfterNChars(String input, int splitLen){
return input.split(String.format("(?<=\\G.{%1$d})", splitLen));
}
Ein Beispiel in IdeOne: http://ideone.com/rNlTj5
Späte Einreise.
Es folgt eine kurze Implementierung unter Verwendung von Java8-Streams, einem Einzeiler:
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();
Ausgabe:
[foo, bar, spa, m]
Dies ist eine späte Antwort, aber ich stelle sie trotzdem für neue Programmierer zur Verfügung:
Wenn Sie keine regulären Ausdrücke verwenden möchten und sich nicht auf eine Bibliothek eines Drittanbieters verlassen möchten, können Sie stattdessen diese Methode verwenden, die in einer 2,80-GHz-CPU (weniger als eine Millisekunde) zwischen 89920 und 100113 Nanosekunden dauert. Es ist nicht so hübsch wie das Beispiel von Simon Nickerson, aber es funktioniert:
/**
* 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()]);
}
Verwenden von einfachem Java:
String s = "1234567890";
List<String> list = new Scanner(s).findAll("...").map(MatchResult::group).collect(Collectors.toList());
System.out.printf("%s%n", list);
Erzeugt die Ausgabe:
[123, 456, 789]
Beachten Sie, dass dadurch übrig gebliebene Zeichen verworfen werden (in diesem Fall 0).
Sie können auch eine Zeichenfolge bei jedem n-ten Zeichen teilen und jeweils in jeden Index einer Liste einfügen:
Hier habe ich eine Liste von Strings mit dem Namen Sequence erstellt:
List <String> Sequenz
Dann teile ich den String "KILOSO" im Grunde alle 2 Wörter. Also würde 'KI' 'LO' 'SO' in einen separaten Index der Liste namens Sequence aufgenommen.
String S = KILOSO
Sequence = Arrays.asList (S.split ("(? <= \ G ..)"));
Also, wenn ich mache:
System.out.print (Sequenz)
Es sollte gedruckt werden:
[KI, LO, SO]
um zu überprüfen, ob ich schreiben kann:
System.out.print (Sequence.get (1))
es wird gedruckt:
LO
Ich bin kürzlich auf dieses Problem gestoßen, und hier ist die Lösung, die ich gefunden habe
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