diff --git a/README.md b/README.md index cf71614..54dcfe4 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ console.log(split('a.b.\\c', { keep: () => true })); //=> ['a', 'b\.c'] ### options.separator -**Type**: `string` +**Type**: `string|Array` **Default**: `.` @@ -153,6 +153,8 @@ The character to split on. ```js console.log(split('a.b,c', { separator: ',' })); //=> ['a.b', 'c'] +console.log(split('a && b && c', { separator: '&&' })); //=> ['a ', ' b ', ' c'] +console.log(split('a&&b||c', { separator: ['||', '&&'] })); //=> ['a', 'b', 'c'] ``` ## Split function @@ -171,6 +173,7 @@ The `state` object exposes the following properties: * `input` - (String) The un-modified, user-defined input string * `separator` - (String) the specified separator to split on. +* `separators` - (Array) the specified separators to split on. * `index` - (Number) The current cursor position * `value` - (String) The character at the current index * `bos` - (Function) Returns true if position is at the beginning-of-string diff --git a/example.js b/example.js index c0a58c4..72b3471 100644 --- a/example.js +++ b/example.js @@ -42,6 +42,8 @@ console.log(split('a.b.\\"c.d."e.f.g".h.i', { quotes: ['"'], keep })); // console.log(split('zzz.{a.{b.{c.{d}.e}.f}.g}.xxx')); // console.log(split('a.{b.c}|{d.e}', { separator: '|' })); +// console.log(split('a.{b.c}|{d.e}', { separator: '||' })); +// console.log(split('a.{b.c}|{d.e}', { separator: ['||', '&&'] })); // console.log(split('a.{b.c}|{d.e}')); // console.log(split('a.{b.c}.{d.e}')); // console.log(split('a.{b.c}.{d.e}', { brackets: false })); diff --git a/index.js b/index.js index 8e2078d..c9c3684 100644 --- a/index.js +++ b/index.js @@ -9,9 +9,10 @@ module.exports = (input, options = {}, fn) => { } let separator = options.separator || '.'; + let separators = typeof separator === 'string' ? [separator] : separator; let ast = { type: 'root', nodes: [], stash: [''] }; let stack = [ast]; - let state = { input, separator, stack }; + let state = { input, separator, separators, stack }; let string = input; let value, node; let i = -1; @@ -112,7 +113,9 @@ module.exports = (input, options = {}, fn) => { } // push separator onto stash - if (value === separator && state.block.type === 'root') { + const usedSeparator = separators.find((sep) => sep === string.substr(i, sep.length)); + if (usedSeparator && state.block.type === 'root') { + i = i + usedSeparator.length - 1; if (typeof fn === 'function' && fn(state) === false) { append(value); continue; diff --git a/test/options.brackets.js b/test/options.brackets.js index cf1ea76..f70cd91 100644 --- a/test/options.brackets.js +++ b/test/options.brackets.js @@ -45,4 +45,12 @@ describe('options.brackets', () => { assert.deepEqual(split('a.{a.{b.c}.d', opts), ['a', '{a', '{b', 'c}', 'd']); assert.deepEqual(split('a.{a.{b.c.d', opts), ['a', '{a', '{b', 'c', 'd']); }); + + it('should take more separators in array with more characters as custom separator and prevent brackets', () => { + const opts = { brackets: true, separator: ['||', '&&'] }; + assert.deepEqual(split('a&&[b&&d]&&c', opts), ['a', '[b&&d]', 'c']); + assert.deepEqual(split('a||[b&&d]&&c', opts), ['a', '[b&&d]', 'c']); + assert.deepEqual(split('a||[b||d]&&c', opts), ['a', '[b||d]', 'c']); + assert.deepEqual(split('[a&&a]&&[b||c]', opts), ['[a&&a]', '[b||c]']); + }); }); diff --git a/test/options.separator.js b/test/options.separator.js index 38e9da6..6bc580a 100644 --- a/test/options.separator.js +++ b/test/options.separator.js @@ -24,5 +24,24 @@ describe('separator', () => { assert.deepEqual(split('a.b.c', state => state.next() !== 'b'), ['a.b', 'c']); assert.deepEqual(split('a.b.c', state => state.next() !== 'c'), ['a', 'b.c']); }); + + it('should take more characters as custom separator', () => { + assert.deepEqual(split('a&&b&&c', { separator: '&&' }), ['a', 'b', 'c']); + assert.deepEqual(split('.a&&b&&c', { separator: '&&' }), ['.a', 'b', 'c']); + assert.deepEqual(split('a||b&&c', { separator: '||' }), ['a', 'b&&c']); + assert.deepEqual(split('a||b&&c', { separator: '&&' }), ['a||b', 'c']); + assert.deepEqual(split('a&&&c', { separator: '&&' }), ['a', '&c']); + assert.deepEqual(split('a&&&&c', { separator: '&&' }), ['a', '', 'c']); + }); + + it('should take more separators in array with more characters as custom separator', () => { + const opts = { separator: ['||', '&&'] }; + assert.deepEqual(split('a&&b&&c', opts), ['a', 'b', 'c']); + assert.deepEqual(split('.a&&b&&c', opts), ['.a', 'b', 'c']); + assert.deepEqual(split('a||b&&c', opts), ['a', 'b', 'c']); + assert.deepEqual(split('a||b&&c', opts), ['a', 'b', 'c']); + assert.deepEqual(split('a&&&c', opts), ['a', '&c']); + assert.deepEqual(split('a&&&&c', opts), ['a', '', 'c']); + }); }); diff --git a/types/index.d.ts b/types/index.d.ts index 583e363..d8eeef7 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -8,7 +8,8 @@ export interface ASTNode { export interface State { input: string; - separator: string; + separator: string | string[]; + separators: string[]; stack: ASTNode[]; bos(): boolean; eos(): boolean; @@ -19,7 +20,7 @@ export interface State { export interface Options { brackets?: { [key: string]: string } | boolean; quotes?: string[] | boolean; - separator?: string; + separator?: string | string[]; strict?: boolean; keep?(value: string, state: State): boolean; }