簡體   English   中英

在每個第 n 個字符處拆分一個字符串

[英]Splitting a string at every n-th character

在 JavaScript 中,這就是我們如何在每個第三個字符處拆分一個字符串

"foobarspam".match(/.{1,3}/g)

我試圖弄清楚如何在 Java 中做到這一點。 任何指針?

你可以這樣做:

String s = "1234567890";
System.out.println(java.util.Arrays.toString(s.split("(?<=\\G...)")));

它產生:

[123, 456, 789, 0]

正則表達式(?<=\\G...)其具有在最后一次匹配(一個空字符串匹配\\G接着是三個字符() ...之前它)( (?<= )

Java 沒有提供非常全功能的拆分實用程序,因此Guava 庫可以:

Iterable<String> pieces = Splitter.fixedLength(3).split(string);

查看SplitterJavadoc 它非常強大。

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

作為Bart Kiers回答的補充,我想補充一點,在正則表達式中,可以不使用三個點...來表示您可以編寫的三個字符.{3} ,它們具有相同的含義。

然后代碼將如下所示:

String bitstream = "00101010001001010100101010100101010101001010100001010101010010101";
System.out.println(java.util.Arrays.toString(bitstream.split("(?<=\\G.{3})")));

有了這個,修改字符串長度會更容易,並且現在使用可變輸入字符串長度創建函數是合理的。 這可以像下面這樣完成:

public static String[] splitAfterNChars(String input, int splitLen){
    return input.split(String.format("(?<=\\G.{%1$d})", splitLen));
}

IdeOne 中的一個例子: http ://ideone.com/rNlTj5

遲到。

以下是使用 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();

輸出:

[foo, bar, spa, m]

這是一個遲到的答案,但無論如何我都會把它放在那里供任何新程序員看到:

如果你不想使用正則表達式不希望依靠第三方庫,你可以用這個方法來代替,這需要納秒89920100113之間的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()]);
    }

使用普通的java:

    String s = "1234567890";
    List<String> list = new Scanner(s).findAll("...").map(MatchResult::group).collect(Collectors.toList());
    System.out.printf("%s%n", list);

產生輸出:

[123, 456, 789]

請注意,這會丟棄剩余的字符(在本例中為 0)。

您還可以在每個第 n 個字符處拆分一個字符串,並將它們每個放在 List 的每個索引中:

在這里,我制作了一個名為 Sequence 的字符串列表:

列表 <String> 序列

然后我基本上每 2 個單詞將字符串“KILOSO”分開。 因此,'KI' 'LO' 'SO' 將被合並到名為 Sequence 的列表的單獨索引中。

字符串 S = KILOSO

序列 = Arrays.asList(S.split("(?<=\\G..)"));

所以當我在做:

System.out.print(序列)

它應該打印:

[KI,LO,SO]

驗證我可以寫:

System.out.print(Sequence.get(1))

它將打印:

LO

我最近遇到了這個問題,這是我想出的解決方案

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

我會從類似的東西開始

public List<String> split(String str, int interval) {
    if (str.length() <= interval) {
        return List.of(str);
    }
    var subStrings = new ArrayList<String>();
    int pointer = 0;
    while (str.length() > pointer) {
        String substring = str.substring(pointer, pointer + interval);
        subStrings.add(substring);
        pointer += interval;
    }
    return subStrings;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM