string-left-right2.3.32

Looks up the first non-whitespace character to the left/right of a given index

§ Quick Take

import { strict as assert } from "assert";
import {
  left,
  right,
  leftSeq,
  rightSeq,
  chompLeft,
  chompRight,
  leftStopAtNewLines,
  rightStopAtNewLines,
} from "string-left-right";

// get the closest non-whitespace character to the left of "d" (which itself
// is at string index 6)
const str = "abc   def";
//             |   |
//           012345678

assert.equal(
  `next non-whitespace character to the left of ${
    str[6]
  } (index 6) is ${str[left(str, 6)]} (index ${left(
    str,
    6
  )})`,
  "next non-whitespace character to the left of d (index 6) is c (index 2)"
);

§ Whole idea

It's trivial to check, is something on the left or on the right of a given index in a string. That's str[i - 1]/str[i + 1]. Done.

It's not that trivial to check, what is the index of the first non-whitespace character on either side. You need to use loops or trim functions and calculate the position, also consider the null cases where there are no such characters.

That's what this program is about — it is a string value lookup helper.

§ API - left() and right()

Both exported functions have the same API:

left(str, [, idx])

right(str, [, idx])

On both, the first input argument is a string, the optional second (marked by brackets above) is a starting index. We "look" to the left or to the right of that index, then report a first non-whitespace character's index on that side. In absence, we return null.

The determinator for whitespace is truthy string.trim().length - the trimmed string must have length; otherwise, it's a whitespace.

These functions allow you to locate the first non-whitespace character on left or right.

For example,

const { left } = require("string-left-right");
// we start at index 2, which is character "b".
const res = left("a b", 2);
// the first non-whitespace character to the left of "b" is "a", at index 0:
console.log(res);
// => 0

The output is either natural number index, pointing to the nearest non-whitespace character on either side or null (if the string ends further, for example).

§ API - chompLeft() and chompRight()

These two allow you to jump over certain repeated characters, possibly spaced out with whitespace.

For example, imagine you have this string:

text x  y xyyyyxxxx       x x x x x yyyy y y y .

Imagine, you are "located" at the index of dot ".", 47. In this case, chompLeft() lets you "jump" over x's and y's and locate the index of a second "t" in "text", 3.

Both exported functions have the same API:

chompLeft(str, idx, [opts], char1, char2, char3...)

chompRight(str, idx, [opts], char1, char2, char3...)

You can pass a plain object - options - as the third argument, or you can omit it.

For example:

const { chompLeft } = require("string-left-right");
// we're saying, jump over all b's and c's when traversing left from "x",
// then report the index of a first non-whitespace string you landed upon (
// or leave space, depending on the chosen mode, see next chapter for its API)
const res1 = chompLeft("a b c b c x y", 12, "b", "c");
console.log(`res1`);
// => 2

// the default mode is 0 and it's omitted, so above example is the same as:
const res2 = chompLeft("a b c b c x y", 12, { mode: 0 }, "b", "c");
console.log(`res2`);
// => 2

§ API - chompLeft() and chompRight() modes

You can pass an options object as a third argument before characters to match.

Modes:

For example:

const { chompLeft } = require("string-left-right");
const res1 = chompLeft("a\n b c b c x y", 13, "b", "c");
console.log(res1);
// => 2
// the default chomp stopped when it reached line break character. It didn't leave a space because it's not a non-whitespace character. If it were not a line break but a letter, it would have stopped one space short of it.

// passing default { mode: 0 } is the same result:
const res2 = chompLeft("a\n b c b c x y", { mode: 0 }, 13, "b", "c");
console.log(res2);
// => 2

// mode 1 - stops at first space met, in this case at first "b"
const res3 = chompLeft("a\n b c b c x y", 12, { mode: "1" }, "b", "c");
console.log(res3);
// => 4
// PS. "\n" counts as length of one

// mode 2 - chomps all whitespace except newlines
// in this case it stops to the right of \n, index 2:
const res4 = chompLeft("a\n b c b c x y", 12, { mode: "2" }, "b", "c");
// => 2

// mode 3 - hungriest of all whitespace chomps - chomps until it meets
// edge of a string or non-whitespace character (one which String.trim()'s
// to non-zero length character):
const res5 = chompLeft("a\n b c b c x y", 12, { mode: "3" }, "b", "c");
// => 1

The chompRight() works the same way, just towards the right side of a given index.

§ API - leftSeq() and rightSeq()

leftSeq() and rightSeq() matches the characters in that order, on the particular side of given index, disregarding the whitespace.

Both exported functions have the same API:

leftSeq(str, idx, [opts], str1ToMatch, str2ToMatch, str3ToMatch... )

rightSeq(str, idx, [opts], str1ToMatch, str2ToMatch, str3ToMatch... )

Above, square brackets mean options are optional, you can omit them.

Input argumentTypeObligatory?Description
strStringyesString to work upon
idxNatural number or zeroyesAt which index we start looking on either side
optsPlain objectnoThe Optional Options Object, see below for its API
str1ToMatchString, single characternoThe first character to match on the sequence
str2ToMatchString, single characternoThe second character to match on the sequence
str3ToMatchString, single characternoThe third character to match on the sequence
...String, single characternoThe n-th character to match on the sequence

You can put as many characters as you want.

Example:

const { leftSeq } = require("string-left-right");
// we start at index 5, that's "f" and look on the left, are there sequence
// of characters "c", "d" and "e", possibly separated by whitespace
const result = leftSeq("abcdefghijk", 5, "c", "d", "e");
// yes, and there are no gaps:
console.log(JSON.stringify(result, null, 4));
// => {
// gaps: [],
// leftmostChar: 2,
// rightmostChar: 4
// }

Now example with gaps:

We're also on "f" and we're also looking left, are the sequence "c", "d", "e" on that side.

t.same(
leftSeq("a b c d e f g h i j k", 15, "c", "d", "e"),
{
gaps: [
[7, 9],
[10, 12],
[13, 15],
],
leftmostChar: 6,
rightmostChar: 12,
},
"04.01.02"
);

Program reports any whitespace gap ranges it encountered and also indexes of leftmost and rightmost character.

§ API - leftStopAtNewLines() and rightStopAtNewLines()

Both exported functions have the same API.

leftStopAtNewLines(str, [, idx])

rightStopAtNewLines(str, [, idx])

On both, the first input argument is a string, the optional second (marked by brackets above) is a starting index.

Both functions are the same as left()/right(), except that besides non-whitespace characters, they also stop at CR and LF, line break characters.

For example,

const { right, rightStopAtNewLines } = require("string-left-right");
const str = "a \n\n\nb";
// right() does not stop at whitespace characters and linebreaks are
// whitespace characters:
const res1 = right(str, 0);
// rightStopAtNewLines() will also stop at line break characters:
const res2 = rightStopAtNewLines(str, 0);
console.log(`res1 = ${res1}; res2 = ${res2}`);
// res1 = 5; res2 = 2

PS. While you type Mac line ending LF as two characters, backwards slash and "n" - \n - it counts as one character.

§ More complex lookups

If you need more complex string lookups, check out string-match-left-right. It can trim whitespace or certain characters before matching.

§ Changelog

See it in the monorepo opens in a new tab, on GitLab.

§ Licence

MIT opens in a new tab

Copyright © 2010–2020 Roy Revelt and other contributors

Related packages:

📦 string-match-left-right 4.0.15
Match substrings on the left or right of a given index, ignoring whitespace
📦 detergent 5.11.13
Extracts, cleans and encodes text
📦 string-collapse-leading-whitespace 3.0.3
Collapse the leading and trailing whitespace of a string
📦 string-overlap-one-on-another 1.5.66
Lay one string on top of another, with an optional offset
📦 string-strip-html 6.3.0
Strips HTML tags from strings. No parser, accepts mixed sources
📦 string-collapse-white-space 7.0.1
Replace chunks of whitespace with a single spaces
📦 string-uglify 1.2.48
Shorten sets of strings deterministically, to be git-friendly