Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java String.split: preserve empty trailing fields in a record

Last updated: 1 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

String.split uses a regular expression and discards trailing empty fields when called without an explicit limit.

A missing field is data

A line ending in a delimiter may mean that the final field was supplied but left blank. The one-argument split method behaves like split(regex, 0), so that field disappears. For a fixed three-field import, split(regex, -1) keeps the trailing empty value and makes validation possible. The code rejects the incomplete record before it can enter the ledger.

The delimiter is a regex. A literal vertical bar therefore needs escaping as \| in the regex, represented as \\| in a Java string literal. Regex matching explains this second parsing layer; strict UTF-8 decoding belongs before any text split of input bytes.

Declare the format limit

This is an internal delimiter format with no quoted fields or escaped delimiters. If a sender can put the delimiter inside a field, split is the wrong parser. Use a format whose escaping rules are specified and a parser that implements those rules. Validate the exact field count, blank policy, and maximum record length before accepting a row.

Splitting creates an array and field strings proportional to input length. For large files, process one bounded line at a time instead of reading the whole file into memory; streaming file reads covers the resource boundary.

Working program

Java
public class ReceiptFieldBoundary {
    static String readReceiptId(String line) {
        if (line == null || line.length() > 256) throw new IllegalArgumentException("record length");
        String[] fields = line.split("\\|", -1);
        if (fields.length != 3 || fields[0].isEmpty() || fields[1].isEmpty() || fields[2].isEmpty())
            throw new IllegalArgumentException("three populated fields required");
        return fields[0];
    }
    public static void main(String[] args) {
        String incomplete = "receipt-47|settled|";
        System.out.println(incomplete.split("\\|").length);
        System.out.println(incomplete.split("\\|", -1).length);
        try { readReceiptId(incomplete); }
        catch (IllegalArgumentException rejected) { System.out.println("record rejected"); }
        System.out.println(readReceiptId("receipt-82|settled|check-15"));
    }
}

Output

Output
2
3
record rejected
receipt-82

Cost and ownership

For a bounded line of n characters, splitting scans O(n) input and allocates O(n) total field content plus the array. The 256-character cap here is a teaching policy, not a universal protocol limit. Choose an application-specific cap before allocating for untrusted input.

Common Mistakes

  • Do not rely on the default split limit when an empty final field has meaning.
  • Do not treat a regex delimiter as a literal string.
  • Do not call a delimiter split a CSV parser when quoted fields are allowed.

Read next

Java regular expressions: full matches, searches and capture boundaries, Java UTF-8 decoding: reject malformed bytes before parsing, Java file I/O: UTF-8, streaming reads, and path ownership, Java console input: Scanner tokens, lines and validation.

Text matching boundaries

Continue with Java String.split limit: retain trailing empty fields in records, Java Pattern.quote: match a supplied token literally.

java
string-split-trailing-fields
Storage details