This is a simple class that lets you navigate within a string. This is useful when creating simple tokenizers for instance.
Print each character in the string
import { StringWalker } from 'string-walker' const str = 'My name is Pontus' const s = new StringWalker(str) while (!s.isEof()) { console.log(s.currentChar()) s.next() } /* Outputs: M y n a m e i s P o n t u s */
Tokenize a simple key/value file
Say we have a key/value file that allows for a syntax like:
key1: strvalue
key2 : 12
key3:some value
We don't care about the whitespace between the key, separator and value
import { StringWalker } from 'string-walker' const str = ` key1: strvalue key2 : 12 key3:some value` const tokens: Array<{ type: string, value: string }> = [] const s = new StringWalker(str) let state: 'key' | 'value' | 'none' = 'none' while (!s.isEof()) { // Consume whitespace if (['\n', ' ', '\t'].includes(s.currentChar())) { s.consume(['\n', ' ', '\t']) } switch (state) { // When state is none we're expecting a key case 'none': { // Find the position of either space, tab or : const end = s.findNextOf([' ', '\t', ':']) // If end is NaN we got to the end of the string without finding // what we are looking for if (isNaN(end)) { throw new Error('Syntax error') } // The key is located from the current position to `end` const key = s.substring(s.position, end) tokens.push({ type: 'key', value: key }) // Now move the cursor to where we found the character s.moveTo(end) state = 'key' break } // When state is `key` we're expecting the next token to be a delimiter case 'key': { if (s.currentChar() !== ':') { throw new Error(`Syntax error: Expected : got ${s.currentChar()}`) } tokens.push({ type: 'delimiter', value: ':' }) // Next we're expecting a value state = 'value' // Move the cursor to the next position s.next() break } case 'value': { // The value should stretch to the end of the line let end = s.findNext('\n') // If end is NaN we've reached the end of the string if (isNaN(end)) { end = s.length } const val = s.substring(s.position, end) tokens.push({ type: 'value', value: val }) s.moveTo(end) // Now we're expecting either whitespace to the end or a new key state = 'none' break } // We should never get here default: throw new Error('Unknown stuff') } } console.log(tokens) /* Expected output: [ { type: 'key', value: 'key1' }, { type: 'delimiter', value: ':' }, { type: 'value', value: 'strvalue' }, { type: 'key', value: 'key2' }, { type: 'delimiter', value: ':' }, { type: 'value', value: '12' }, { type: 'key', value: 'key3' }, { type: 'delimiter', value: ':' }, { type: 'value', value: 'some value' } ] */