LOG
2026_0110
sends hook 'pattern_part' boolean parameter. Example use:
  split({around:quotedSubstring,string: `before "mid" end`})
  hook receives [`before `,…,0] |> [`"mid"`…,1] |> [` end`,…,0]

2026_0103
adds 'match' mode, to collect pattern matches only, and example
adds log to readme page

2025_1026
add 'hook' property, to send each part through fn
refactors the 'at' mode to work the same way as others
moves all 'keep' string logic to one function, and slims code

2025_1010
add 'around' mode:
  split({around:/\d+/,})(`a12b34c`)// ["a","12","b","34","c"]

adds 'trim' option to trim all strings in list
refactors
renames to 'split_string()' for grep (avoids `.split` mismatch)

2025_1009
packs various split methods into basic function
reduces code repetition
makes function curry-able/chainable/pipe-able
simplifies use:
  split({at/before/after:delimiter_regex_or_str})(str)
  (VS. split({delimiter:re_or_str,mode:before|after|at})(str))
Up
Split String - A JavaScript Function
© 2025 Greg Abbott


/*
(Minified 1.4KB)
Split a string ['Before', 'At', 'After', 'Around']
every occurrence of a regular expression or string delimiter,
infinitely, or into a maximum number of parts.

// EXAMPLE USES ================================================
// BEFORE splits before each occurrence of the pattern
  // It adds text matching the pattern to the start of items
  split({
    before: /\band\b/,
    string:'you and me'
  })
  // ['you ','and me']

// AT works like .split()
  split({
    at: '|',
    seed: new Set() // to collect only unique values, use a Set
  })('a|b|c|b|a|c|d|e') 
  // To use the function in a chain, omit the string property:
  // e.g. chain(string_to_split,split({config}),act_on_results)
  // ['a','b','c','d','e']

// AFTER splits after each occurrence of the pattern
  // It adds text matching the pattern to the end of items
  // optionally setup a splitter fn to reuse
  let split_after_comma = split({after: ', '})
  
  split_after_comma('hello, world')
  // ['hello, ','world']
  split_after_comma('world, wide, web')
  // ['world, ','wide, ','web']

// AROUND
// The split around mode processes:
//   each substring before the pattern
//   each occurrence of the text matching the pattern
//   each substring after the pattern
// It works well with marked up text, parentheses and quotes

  // Define a pattern
  const text_in_parentheses =
    /(^|\s)\([^\s)](?:[^)]*[^\s)])?\)[!?.:;,]?/g

  split({
    around: text_in_parentheses,
    // provide an optional hook to transform substrings:
    hook:(x,i,acc)=>{acc.push(x.trim())}
      // hooks control what to do and which items to collect
      // (vs. automatic accumulation without a hook)
  })(`before (comment1) middle (comment2) after`)
  // [`before`,`(comment1)`,`middle`,`(comment2)`,`after`]

// MATCH works like .match() and only keeps pattern matches
  
  split({
    match:/\d+/,
    seed:[],
    string:`abc123def456ghi789`,
  })
  // [ "123", "456", "789" ]

// STOP EARLY stop when done, based on any condition
// The hook below stops early, after collecting 3 parts
  split({
    at:',',
    hook:(x,i,acc,stop)=>{
      acc.push(x)//collect
      if(acc.length===3)return stop
    }
  })('a,b,c,d,e,...')

// EXISTING ARRAYS
// Split a string directly into an existing array or set
let existing_array = ['a','b','c']

// Add results to an existing array or set
split({
  at:',',
  seed:existing_array
})(`d,e,f`)
// ['a','b','c','d','e','f']

// Replace the content of an existing array or set
split({
  at:',',
  seed:existing_array,
  clear_seed:true
})(`9,8,7,6`)
*/