Easy way to split a string on a given character unless it's quoted or escaped
npx @tessl/cli install tessl/npm-split-string@6.1.0Split String is a JavaScript utility library that provides intelligent string splitting functionality. Unlike the native String.split() method, it respects escaped characters, quoted strings, and nested bracket structures, making it ideal for parsing configuration strings, comma-separated values, and other structured text formats.
npm install split-stringconst split = require('split-string');ESM import (requires transpilation or Node.js with ESM support):
import split from 'split-string';TypeScript (using CommonJS require with type definitions):
import split = require('split-string');
import type { Options, State, ASTNode } from 'split-string';const split = require('split-string');
// Basic splitting on dots
console.log(split('a.b.c'));
//=> ['a', 'b', 'c']
// Respects escaped characters
console.log(split('a.b.c\\.d'));
//=> ['a', 'b', 'c.d']
// Respects quoted strings (when quotes option is provided)
console.log(split('a."b.c.d".e', { quotes: ['"'] }));
//=> ['a', '"b.c.d"', 'e']
// Without quotes option, splits inside quoted strings
console.log(split('a."b.c.d".e'));
//=> ['a', '"b', 'c', 'd"', 'e']
// Respects nested brackets
console.log(split('a.{b.c}.d', { brackets: true }));
//=> ['a', '{b.c}', 'd']The primary function for splitting strings with intelligent parsing that respects quotes, brackets, and escape sequences. Has multiple overloads for different usage patterns.
/**
* Split a string on a given character unless it's quoted or escaped
*/
function split(input: string): string[];
function split(input: string, options: Options): string[];
function split(input: string, fn: SplitFunc): string[];
function split(input: string, options: Options, fn: SplitFunc): string[];Usage Examples:
// Custom separator
split('a|b|c', { separator: '|' });
//=> ['a', 'b', 'c']
// Multiple quote types
split('a."b.c".\'d.e\'.f', { quotes: ['"', "'"] });
//=> ['a', '"b.c"', "'d.e'", 'f']
// Custom bracket pairs
split('a.[b.c].<d.e>.f', { brackets: { '[': ']', '<': '>' } });
//=> ['a', '[b.c]', '<d.e>', 'f']
// Conditional splitting with custom function
split('a.b.c.d.e', (state) => state.prev() !== 'b');
//=> ['a', 'b.c', 'd', 'e']Options for customizing the splitting behavior.
/**
* Configuration options for split function
* @typedef {Object} Options
* @property {Object|boolean} [brackets] - Bracket pair definitions or true for default brackets
* @property {string[]|boolean} [quotes] - Array of quote characters or true for default quotes
* @property {string} [separator='.'] - Character to split on
* @property {boolean} [strict=false] - Whether to throw on unmatched brackets
* @property {KeepFunc} [keep] - Function to determine which characters to keep
*/Default Values:
separator: '.'brackets: false (disabled by default)quotes: [] (empty array, disabled by default)strict: falsekeep: Function that excludes backslashesBracket Configuration:
// Enable all default brackets
{ brackets: true }
// Equivalent to: { brackets: { '[': ']', '(': ')', '{': '}', '<': '>' } }
// Custom bracket pairs (keys are opening brackets, values are closing brackets)
{ brackets: { '«': '»', '⟨': '⟩' } }
// Disabled (default behavior)
{ brackets: false } // or omit the propertyQuote Configuration:
// Enable all default quotes
{ quotes: true }
// Equivalent to: { quotes: ['"', "'", '`'] }
// Custom quote characters (each character serves as both opener and closer)
{ quotes: ['"', '~'] }
// Disabled (default behavior)
{ quotes: [] } // or omit the propertyFunction type for implementing custom splitting logic.
/**
* Custom function for controlling split behavior
* @callback SplitFunc
* @param {State} state - Current parsing state
* @returns {boolean} Whether to allow splitting at current position (false prevents split)
*/Usage Example:
// Only split when previous character is not 'a'
const customSplit = (state) => state.prev() !== 'a';
split('a.b.c.a.d.e', customSplit);
//=> ['a.b.c.a', 'd.e']State information available to custom functions and keep functions.
/**
* Parsing state information passed to custom functions and keep functions
* @typedef {Object} State
* @property {string} input - Original input string
* @property {string} separator - Current separator character
* @property {ASTNode[]} stack - Stack of AST nodes being processed
* @property {string} value - Current character value (set during parsing)
* @property {number} index - Current character index (set during parsing)
* @property {ASTNode} block - Current AST block (set during parsing)
* @property {function(): boolean} bos - Returns true if at beginning of string
* @property {function(): boolean} eos - Returns true if at end of string
* @property {function(): string} prev - Returns previous character
* @property {function(): string} next - Returns next character
*/Function for filtering characters during parsing.
/**
* Function to determine which characters to keep in the output
* @callback KeepFunc
* @param {string} value - Current character being processed
* @param {State} state - Current parsing state
* @returns {boolean} Whether to keep the character (false excludes it)
*/Usage Example:
// Keep all characters except backslashes and unescaped quotes
const keepFunc = (value, state) => {
return value !== '\\' && (value !== '"' || state.prev() === '\\');
};
split('a.b.\\"c.d."e.f.g".h.i', { quotes: ['"'], keep: keepFunc });
//=> ['a', 'b', '"c', 'd', 'e.f.g', 'h', 'i']Internal abstract syntax tree node structure used during parsing.
/**
* Abstract syntax tree node structure used internally during parsing
* @typedef {Object} ASTNode
* @property {'root'|'bracket'} type - Node type ('root' for main document, 'bracket' for bracketed sections)
* @property {ASTNode[]} nodes - Child nodes
* @property {string[]} stash - Accumulated string segments
* @property {ASTNode} [parent] - Parent node reference (undefined for root)
*/The function handles various error conditions:
// Error examples
try {
split(123); // TypeError: expected a string
} catch (error) {
console.error(error.message);
}
try {
split('a.{b.c', { brackets: true, strict: true }); // SyntaxError: Unmatched
} catch (error) {
console.error(error.message);
}
// Non-strict mode handles unmatched brackets gracefully
split('a.{b.c', { brackets: true });
//=> ['a', '{b', 'c']// Parse dotted configuration paths
const config = 'database.connection.host';
const parts = split(config);
//=> ['database', 'connection', 'host']
// Handle escaped dots in values
const configWithEscapes = 'app.name.my\\.app\\.name';
const parts2 = split(configWithEscapes);
//=> ['app', 'name', 'my.app.name']// Parse quoted CSV fields
const csvField = 'name,"Smith, John",age';
const fields = split(csvField, { separator: ',', quotes: ['"'] });
//=> ['name', '"Smith, John"', 'age']// Parse object-like strings
const objectString = 'a.{b.{c.d}.e}.f';
const parsed = split(objectString, { brackets: true });
//=> ['a', '{b.{c.d}.e}', 'f']
// Parse arrays and mixed brackets
const mixedString = 'a.[b.{c.d}].e';
const mixed = split(mixedString, { brackets: true });
//=> ['a', '[b.{c.d}]', 'e']