Skip to main content Link Search Menu Expand Document (external link)

String overview

Extension to the Effect String module: stringification of unknown / primitive values, indexed search, custom-character trimming, padding, splitting (including bit-aligned chunking), indented multi-line formatting, and lightweight string predicates (SemVer, e-mail, digit, …).

Mental model

  • All functions are pure, data-last, and treat strings as immutable values.
  • Search helpers ({@link search}, {@link searchAll}, {@link searchRight}) accept either a literal string (no escaping needed) or a RegExp. They return positions through {@link “./StringSearchResult.js” | MStringSearchResult}.
  • Both regex-based searches and {@link match} / {@link matches} reset lastIndex before use, so passing a RegExp literal with the g flag is safe but global matches are not iterated; only the first match is returned (use {@link searchAll} for all).

Common tasks

  • Stringify: {@link fromUnknown}, {@link fromPrimitive}, {@link fromNonNullablePrimitive}, {@link fromNumber}
  • Search: {@link search}, {@link searchAll}, {@link searchRight}, {@link count}
  • Slice: {@link takeBut}, {@link takeRightBut}, {@link takeTo}, {@link takeRightFrom}
  • Trim / strip / pad: {@link trimStart}, {@link trimEnd}, {@link trim}, {@link stripLeft}, {@link stripLeftOption}, {@link stripRight}, {@link stripRightOption}, {@link pad}
  • Combine: {@link append}, {@link appendIfNotEmpty}, {@link prepend}, {@link prependIfNotEmpty}, {@link surroundIfNotEmpty}, {@link replaceBetween}
  • Match: {@link match}, {@link matches}, {@link matchWithCapturingGroups}
  • Split: {@link splitAt}, {@link splitAtFromRight}, {@link splitEquallyRestAtStart}, {@link splitEquallyRestAtEnd}
  • Format: {@link tabify}, {@link removeNCharsEveryMCharsFromRight}
  • Predicates: {@link isMultiLine}, {@link isSemVer}, {@link isEmail}, {@link hasLength}, {@link isDigit}

Quickstart

Example (Indexed search and padding)

import { Option, pipe } from "effect"
import * as MString from "@parischap/effect-lib/MString"
import * as MStringFillPosition from "@parischap/effect-lib/String/StringFillPosition"

const found = pipe("hello world", MString.search("world"))
console.log(Option.map(found, (r) => r.startIndex)) // Some(6)

console.log(pipe("42", MString.pad({ length: 5, fillChar: "0", fillPosition: MStringFillPosition.Type.Left })))
// '00042'

Table of contents


Constructors

fromNonNullablePrimitive

Builds a string from a primitive value other than null and undefined.

  • Numbers and BigInts are converted using base-10 (not scientific notation).
  • Other primitives use their .toString() method.
  • Returns string representation suitable for display or further processing.

Example (Convert non-nullable primitive)

import * as MString from '@parischap/effect-lib/String/String';

console.log(MString.fromNonNullablePrimitive(42)); // "42"
console.log(MString.fromNonNullablePrimitive(true)); // "true"
console.log(MString.fromNonNullablePrimitive(3.14n)); // "3.14"

Signature

export declare const fromNonNullablePrimitive: (u: MTypes.NonNullablePrimitive) => string

fromNumber

Converts a number to a string using a specified radix.

  • Radix 10 with non-scientific numbers uses the special fixed-point conversion.
  • Other radixes and BigInt use native .toString(radix).
  • Decimal parts preserved for floating-point numbers.
  • Handles very large and very small numbers without scientific notation.

Example (Convert to string with radix)

import * as MString from "@parischap/effect-lib/String/String"

const toBase10 = MString.fromNumber(10)
console.log(toBase10(255)) // "255"
console.log(toBase10(1e-10)) // "0.0000000001"

const toBase16 = MString.fromNumber(16)
console.log(toBase16(255)) // "ff"

Signature

export declare const fromNumber: (radix: number) => MTypes.OneArgFunction<number | bigint, string>

fromPrimitive

Builds a string from a primitive value, handling null and undefined.

  • null converts to "null" and undefined to "undefined".
  • Non-nullable primitives delegated to {@link fromNonNullablePrimitive}.
  • Numbers and BigInts use base-10 conversion (no scientific notation).

Example (Convert nullable primitive)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.fromPrimitive(null)) // "null"
console.log(MString.fromPrimitive(undefined)) // "undefined"
console.log(MString.fromPrimitive(123)) // "123"
console.log(MString.fromPrimitive(false)) // "false"

Signature

export declare const fromPrimitive: MTypes.OneArgFunction<MTypes.Primitive, string>

fromUnknown

Builds a string from an unknown value.

  • Primitives delegated to {@link fromPrimitive}.
  • Objects serialized via JSON.stringify with 2-space indentation.
  • Use for debugging or logging arbitrary values.

Example (Convert unknown value)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.fromUnknown(42)) // "42"
console.log(MString.fromUnknown({ x: 1 }))
// "{\n  \"x\": 1\n}"

Signature

export declare const fromUnknown: (u: unknown) => string

Destructors

matchWithCapturingGroups

Matches a regex pattern and extracts named capturing groups.

  • Throws if regex has g flag or missing expected named groups.
  • Returns Option.some with match text and group values.
  • Undefined optional capturing groups converted to empty strings.
  • Use for structured pattern extraction (named groups).
  • Type-safe group extraction based on capturingGroupNames array.

Example (Extract named groups)

import { Option } from "effect"
import * as MString from "@parischap/effect-lib/MString"

const result = MString.matchWithCapturingGroups(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/, [
  "year",
  "month",
  "day"
] as const)("2024-05-01")
if (Option.isSome(result)) {
  console.log(result.value.groups.year) // '2024'
}

Signature

export declare const matchWithCapturingGroups: <const Names extends ReadonlyArray<string>>(
  regExp: RegExp,
  capturingGroupNames: Names
) => (
  self: Type
) => Option.Option<{ match: string; groups: { [k in keyof Names as [k] extends [number] ? Names[k] : never]: string } }>

Models

Type (type alias)

Type on which this module’s functions operate

Signature

export type Type = string

Predicates

hasLength

Tests whether the string has exactly the specified length.

  • Returns true if self.length === l.
  • Returns false otherwise.
  • Use for length validation in predicates or guards.

Example (Test length)

import * as MString from "@parischap/effect-lib/String/String"

const isLengthFive = MString.hasLength(5)
console.log(isLengthFive("hello")) // true
console.log(isLengthFive("hi")) // false

Signature

export declare const hasLength: (l: number) => Predicate.Predicate<Type>

isDigit

Tests whether the string is a single ASCII digit character (09).

  • Returns true only for strings of exactly 1 character in range [0-9].
  • Returns false for multi-character strings or non-digit characters.
  • Returns false for non-ASCII digits.
  • Use to validate single numeric digit input.

Example (Test digit character)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.isDigit("5")) // true
console.log(MString.isDigit("0")) // true
console.log(MString.isDigit("55")) // false
console.log(MString.isDigit("a")) // false

Signature

export declare const isDigit: Predicate.Predicate<string>

isEmail

Tests whether the string is a valid email address.

  • Uses internal email regex for validation.
  • Returns true if matches email pattern, false otherwise.
  • Note: No format is fully RFC-compliant; use for basic validation.
  • Use to validate user input emails.

Example (Test email)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.isEmail("user@example.com")) // true
console.log(MString.isEmail("invalid.email")) // false

Signature

export declare const isEmail: Predicate.Predicate<string>

isMultiLine

Tests whether the string contains line break characters.

  • Returns true if any end-of-line character found (platform-independent).
  • Returns false for single-line strings.
  • Uses internal lineBreak regex for detection.
  • Use to distinguish single-line from multi-line strings.

Example (Test for multiple lines)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.isMultiLine("hello")) // false
console.log(MString.isMultiLine("hello\nworld")) // true

Signature

export declare const isMultiLine: Predicate.Predicate<string>

isSemVer

Tests whether the string is a valid semantic version.

  • Format: major.minor.patch[-prerelease][+build].
  • Uses internal semVer regex for validation.
  • Returns true if matches SemVer spec, false otherwise.
  • Use to validate version strings.

Example (Test semantic version)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.isSemVer("1.0.0")) // true
console.log(MString.isSemVer("1.0.0-alpha")) // true
console.log(MString.isSemVer("1.0")) // false

Signature

export declare const isSemVer: Predicate.Predicate<string>

matches

Tests whether the string matches a regex pattern.

  • Type guard version of {@link match} returning boolean.
  • Ignores g flag; always checks single match.
  • Resets lastIndex before matching; safe with global regexps.
  • Returns true if pattern matches, false otherwise.
  • Use for predicate checks without extracting match text.

Example (Test pattern match)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.matches(/^[A-Z]/)("Hello")) // true
console.log(MString.matches(/^[a-z]/)("Hello")) // false

Signature

export declare const matches: (regExp: RegExp) => Predicate.Predicate<Type>

Utils

append

Appends a string to the end.

  • Simple concatenation: self + s.
  • No trimming or normalization applied.
  • Returns new string without modifying input.
  • Use for unconditional concatenation.

Example (Append string)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.append(".txt")("readme")) // "readme.txt"
console.log(MString.append("!")("hello")) // "hello!"

Signature

export declare const append: (s: string) => MTypes.StringTransformer

appendIfNotEmpty

Appends a string only if the original string is non-empty.

  • Returns s appended if string length > 0.
  • Returns empty string if input string is empty.
  • Use to conditionally add suffixes to non-empty strings.
  • Common for adding punctuation or delimiters.

Example (Append if not empty)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.appendIfNotEmpty("!")("hello")) // "hello!"
console.log(MString.appendIfNotEmpty("!")("")) // ""

Signature

export declare const appendIfNotEmpty: (s: string) => MTypes.StringTransformer

count

Counts non-overlapping occurrences of a pattern in the string.

  • Supports both string patterns and RegExp patterns.
  • Counts all non-overlapping matches found via {@link searchAll}.
  • Returns 0 if no matches found.
  • Use for pattern frequency analysis.

Example (Count occurrences)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.count("o")("hello world")) // 2
console.log(MString.count(/[aeiou]/g)("hello world")) // 3

Signature

export declare const count: (regexp: RegExp | string) => MTypes.NumberFromString

match

Finds first regex match without side effects.

  • Uses RegExp.prototype.exec instead of String.prototype.match.
  • Ignores the g flag; always returns only first match.
  • Resets lastIndex before matching; safe with global regexps.
  • Returns Option.some with matched text or Option.none.
  • Use when you need single match without g flag complications.

Example (Match pattern)

import { Option, pipe } from "effect"
import * as MString from "@parischap/effect-lib/MString"

const result = pipe("abc123def", MString.match(/\d+/))
console.log(Option.getOrElse(result, () => "")) // '123'

Signature

export declare const match: (regExp: RegExp) => (self: Type) => Option.Option<string>

pad

Pads a string to a specific length with a fill character.

  • fillChar must be a single character (default behavior for longer strings unspecified).
  • If string length already meets target, no change applied.
  • fillPosition determines whether padding added to left or right.
  • length should be a positive integer.
  • Returns new string or original if already long enough.

Example (Pad string)

import * as MString from "@parischap/effect-lib/String/String"
import * as MStringFillPosition from "@parischap/effect-lib/String/StringFillPosition"

const padLeft = MString.pad({
  length: 10,
  fillChar: "0",
  fillPosition: MStringFillPosition.Type.Left
})
console.log(padLeft("42")) // "00000042"

Signature

export declare const pad: ({
  length,
  fillChar,
  fillPosition
}: {
  readonly length: number
  readonly fillChar: string
  readonly fillPosition: MStringFillPosition.Type
}) => MTypes.OneArgFunction<Type>

prepend

Prepends a string to the beginning.

  • Simple concatenation: s + self.
  • No trimming or normalization applied.
  • Returns new string without modifying input.
  • Use for unconditional concatenation.

Example (Prepend string)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.prepend("http://")("example.com")) // "http://example.com"
console.log(MString.prepend("Hello ")("World")) // "Hello World"

Signature

export declare const prepend: (s: string) => MTypes.StringTransformer

prependIfNotEmpty

Prepends a string only if the original string is non-empty.

  • Returns s prepended if string length > 0.
  • Returns empty string if input string is empty.
  • Use to conditionally add prefixes to non-empty strings.
  • Common for adding protocol or namespace prefixes.

Example (Prepend if not empty)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.prependIfNotEmpty(">>> ")("log message")) // ">>> log message"
console.log(MString.prependIfNotEmpty(">>> ")("")) // ""

Signature

export declare const prependIfNotEmpty: (s: string) => MTypes.StringTransformer

removeNCharsEveryMCharsFromRight

Removes n characters from every m-character chunk from the right.

  • Splits string into (m + n)-character chunks.
  • Keeps first m characters of each chunk.
  • Discards last n characters of each chunk.
  • If n === 0, returns string unchanged.
  • m and n must be positive integers.
  • Use for removing trailing characters at regular intervals (e.g., removing formatting).

Example (Remove characters at intervals)

import * as MString from "@parischap/effect-lib/String/String"

const removeHyphens = MString.removeNCharsEveryMCharsFromRight({
  m: 3,
  n: 1
})
console.log(removeHyphens("123-456-789-")) // "123456789"

Signature

export declare const removeNCharsEveryMCharsFromRight: ({
  m,
  n
}: {
  readonly m: number
  readonly n: number
}) => MTypes.StringTransformer

replaceBetween

Replaces the substring between two indexes.

  • If startIndex === endIndex, replacement is inserted at that position.
  • If startIndex > endIndex, characters between them appear before and after replacement.
  • Negative indexes clamped to 0; overlong indexes clamped to string length.
  • Returns new string with replacement applied.
  • Use for substring replacement without regex complexity.

Example (Replace between indexes)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.replaceBetween("***", 5, 10)("hello world")) // "hello*** world"
console.log(MString.replaceBetween("X", 3, 3)("abc")) // "abcX"

Signature

export declare const replaceBetween: (
  replacement: string,
  startIndex: number,
  endIndex: number
) => MTypes.StringTransformer

Searches for the first occurrence of a pattern in the string.

  • Supports both string literals (without escaping special characters) and RegExp patterns.
  • Optionally starts search from startIndex (default 0).
  • The g flag on RegExp is ignored; only first match returned.
  • Returns Option.some with match details or Option.none if not found.
  • Match details include start/end indexes and matched text.

Example (Search for first occurrence)

import { pipe } from "effect"
import * as Option from "effect/Option"
import * as MString from "@parischap/effect-lib/String/String"

const text = "The quick brown fox"
const result = pipe(text, MString.search("quick"))
console.log(Option.isSome(result)) // true
if (Option.isSome(result)) {
  console.log(result.value.match) // "quick"
}

Signature

export declare const search: (
  regexp: RegExp | string,
  startIndex?: number
) => (self: Type) => Option.Option<MStringSearchResult.Type>

searchAll

Searches for all non-overlapping occurrences of a pattern.

  • Supports both string patterns and RegExp patterns.
  • The g flag is ignored; uses internal search loop.
  • Returns array of all match results with indexes and matched text.
  • Returns empty array if no matches found.
  • Use to iterate over all occurrences.

Example (Find all occurrences)

import { pipe } from "effect"
import * as MString from "@parischap/effect-lib/String/String"

const text = "apple apple apple"
const matches = pipe(text, MString.searchAll("apple"))
console.log(matches.length) // 3
console.log(matches[0].match) // "apple"

Signature

export declare const searchAll: (regexp: RegExp | string) => (self: Type) => Array<MStringSearchResult.Type>

searchRight

Searches for the last (rightmost) occurrence of a pattern.

  • Supports both string patterns and RegExp patterns.
  • The g flag is ignored; uses internal search.
  • Returns Option.some with last match details or Option.none if not found.
  • More efficient than calling {@link searchAll} for finding the last match.

Example (Find last occurrence)

import { pipe } from "effect"
import * as Option from "effect/Option"
import * as MString from "@parischap/effect-lib/String/String"

const text = "one two one three"
const result = pipe(text, MString.searchRight("one"))
if (Option.isSome(result)) {
  console.log(result.value.startIndex) // 8
}

Signature

export declare const searchRight: (regexp: RegExp | string) => (self: Type) => Option.Option<MStringSearchResult.Type>

splitAt

Splits string at a specific position into two parts.

  • First part: characters 0 to n-1 (length = n).
  • Second part: remaining characters.
  • Negative n clamped to 0; n > length clamped to length.
  • Returns tuple [left, right] always.
  • Use for position-based string bisection.

Example (Split at position)

import * as MString from "@parischap/effect-lib/String/String"

const [left, right] = MString.splitAt(5)("hello world")
console.log(left) // "hello"
console.log(right) // " world"

Signature

export declare const splitAt: (n: number) => (self: Type) => [left: string, right: string]

splitAtFromRight

Splits string at a position measured from the end.

  • Second part: last n characters (length = n).
  • First part: remaining characters.
  • Negative n clamped to 0; n > length clamped to length.
  • Returns tuple [left, right] always.
  • Use for suffix extraction with known length.

Example (Split at position from right)

import * as MString from "@parischap/effect-lib/String/String"

const [left, right] = MString.splitAtFromRight(5)("hello world")
console.log(left) // "hello "
console.log(right) // "world"

Signature

export declare const splitAtFromRight: (n: number) => (self: Type) => [left: string, right: string]

splitEquallyRestAtEnd

Splits string into equal chunks with remainder at end.

  • Chunks are bitSize characters each.
  • Last chunk may have 1 to bitSize characters (remainder).
  • Preceding chunks are exactly bitSize characters.
  • bitSize must be strictly positive.
  • Returns non-empty array of chunks.
  • Use for fixed-width chunking with trailing remainder.

Example (Split equally with remainder last)

import * as MString from "@parischap/effect-lib/String/String"

const result = MString.splitEquallyRestAtEnd(3)("abcdefgh")
console.log(result) // ["abc", "def", "gh"]

Signature

export declare const splitEquallyRestAtEnd: (bitSize: number) => MTypes.OneArgFunction<Type, MTypes.OverOne<string>>

splitEquallyRestAtStart

Splits string into equal chunks with remainder at start.

  • Chunks are bitSize characters each.
  • First chunk may have 1 to bitSize characters (remainder).
  • Remaining chunks are exactly bitSize characters.
  • bitSize must be strictly positive.
  • Returns reversed array from internal unfold.
  • Use for fixed-width formatting with leading remainder.

Example (Split equally with remainder first)

import * as MString from "@parischap/effect-lib/String/String"

const result = MString.splitEquallyRestAtStart(3)("abcdefgh")
console.log(result) // ["ab", "cde", "fgh"] or similar

Signature

export declare const splitEquallyRestAtStart: (bitSize: number) => MTypes.OneArgFunction<Type, Array<string>>

stripLeft

Removes a prefix from the string if present.

  • Returns string without prefix if prefix matches.
  • Returns original string if prefix not found.
  • Always returns a string (never Option).
  • Use for unconditional prefix removal.

Example (Strip prefix)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.stripLeft("http://")("http://example.com")) // "example.com"
console.log(MString.stripLeft("https://")("http://example.com")) // "http://example.com"

Signature

export declare const stripLeft: (s: string) => MTypes.StringTransformer

stripLeftOption

Optionally removes a prefix from the start of the string.

  • Returns Option.some with stripped string if prefix matches.
  • Returns Option.none if string doesn’t start with prefix.
  • Returns new string with prefix removed or Option.none.
  • Use in optional chains where missing prefix is valid.

Example (Strip prefix optionally)

import { pipe } from "effect"
import * as Option from "effect/Option"
import * as MString from "@parischap/effect-lib/String/String"

const result = pipe("file.txt", MString.stripLeftOption("file"))
console.log(Option.isSome(result)) // true
console.log(Option.getOrElse(result, () => "")) // ".txt"

Signature

export declare const stripLeftOption: (s: string) => MTypes.OneArgFunction<Type, Option.Option<string>>

stripRight

Removes a suffix from the string if present.

  • Returns string without suffix if suffix matches.
  • Returns original string if suffix not found.
  • Always returns a string (never Option).
  • Use for unconditional suffix removal.

Example (Strip suffix)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.stripRight(".txt")("readme.txt")) // "readme"
console.log(MString.stripRight(".md")("readme.txt")) // "readme.txt"

Signature

export declare const stripRight: (s: string) => MTypes.StringTransformer

stripRightOption

Optionally removes a suffix from the end of the string.

  • Returns Option.some with stripped string if suffix matches.
  • Returns Option.none if string doesn’t end with suffix.
  • Returns new string with suffix removed or Option.none.
  • Use in optional chains where missing suffix is valid.

Example (Strip suffix optionally)

import { pipe } from "effect"
import * as Option from "effect/Option"
import * as MString from "@parischap/effect-lib/String/String"

const result = pipe("file.txt", MString.stripRightOption(".txt"))
console.log(Option.isSome(result)) // true
console.log(Option.getOrElse(result, () => "")) // "file"

Signature

export declare const stripRightOption: (s: string) => MTypes.OneArgFunction<Type, Option.Option<string>>

surroundIfNotEmpty

Surrounds string with prefix and suffix if non-empty.

  • Returns prefix + self + suffix if string length > 0.
  • Returns empty string if input string is empty.
  • Use to wrap content with delimiters or markup (quotes, tags, etc.).
  • Useful for formatting output conditionally.

Example (Surround if not empty)

import * as MString from "@parischap/effect-lib/String/String"

const quoted = MString.surroundIfNotEmpty({
  prefix: '"',
  suffix: '"'
})
console.log(quoted("hello")) // '"hello"'
console.log(quoted("")) // ""

Signature

export declare const surroundIfNotEmpty: ({
  prefix,
  suffix
}: {
  readonly prefix: string
  readonly suffix: string
}) => MTypes.StringTransformer

tabify

Adds indentation to each line in the string.

  • Prepends tabChar repeated count times to each line.
  • First line indented; subsequent lines indented after line breaks.
  • Default count is 1.
  • Uses internal lineBreak regex for platform-independent handling.
  • Returns new string with consistent indentation.
  • Use for pretty-printing multi-line content.

Example (Add indentation)

import * as MString from "@parischap/effect-lib/String/String"

const result = MString.tabify("  ", 1)("line1\nline2\nline3")
console.log(result)
// "  line1\n  line2\n  line3"

Signature

export declare const tabify: (tabChar: string, count?: number) => MTypes.StringTransformer

takeBut

Returns substring excluding the last n characters.

  • If n is negative, string returned unchanged.
  • If n greater than string length, empty string returned.
  • Use to trim a known suffix length without searching.
  • Inverse of {@link takeRight} semantically.

Example (Take all but last n characters)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.takeBut(3)("hello")) // "he"
console.log(MString.takeBut(-1)("hello")) // "hello"

Signature

export declare const takeBut: (n: number) => MTypes.StringTransformer

takeRightBut

Returns substring excluding the first n characters.

  • If n is negative, string returned unchanged.
  • If n greater than string length, empty string returned.
  • Use to skip a known prefix length without searching.
  • Inverse of {@link String.takeLeft} semantically.

Example (Take all but first n characters)

import * as MString from "@parischap/effect-lib/String/String"

console.log(MString.takeRightBut(3)("hello")) // "lo"
console.log(MString.takeRightBut(-1)("hello")) // "hello"

Signature

export declare const takeRightBut: (n: number) => MTypes.StringTransformer

takeRightFrom

Extracts substring from first occurrence of pattern to end.

  • Returns characters after the first pattern match.
  • Returns full string if pattern not found.
  • Supports both string patterns and RegExp (without escaping requirements).
  • Use to split at first occurrence and keep the part after delimiter.

Example (Take from pattern to end)

import { pipe } from "effect"
import * as MString from "@parischap/effect-lib/String/String"

const text = "hello@world.com"
const result = pipe(text, MString.takeRightFrom("@"))
console.log(result) // "world.com"

Signature

export declare const takeRightFrom: (regexp: RegExp | string) => MTypes.StringTransformer

takeTo

Extracts substring from start up to first occurrence of pattern.

  • Returns characters before the first pattern match.
  • Returns full string if pattern not found.
  • Supports both string patterns and RegExp (without escaping requirements).
  • Use to split at first occurrence without including the delimiter.

Example (Take up to pattern)

import { pipe } from "effect"
import * as MString from "@parischap/effect-lib/String/String"

const text = "hello@world.com"
const result = pipe(text, MString.takeTo("@"))
console.log(result) // "hello"

Signature

export declare const takeTo: (regexp: RegExp | string) => MTypes.StringTransformer

trim

Removes padding characters from left or right of a string.

  • Only removes characters matching fillChar (single character).
  • Direction determined by fillPosition.
  • Removes all contiguous matching characters from that side.
  • Returns original string if no matching characters found.
  • Use to reverse padding or strip known suffixes/prefixes.

Example (Trim padding)

import * as MString from "@parischap/effect-lib/String/String"
import * as MStringFillPosition from "@parischap/effect-lib/String/StringFillPosition"

const trimRight = MString.trim({
  fillChar: ".",
  fillPosition: MStringFillPosition.Type.Right
})
console.log(trimRight("file.txt...")) // "file.txt"

Signature

export declare const trim: ({
  fillChar,
  fillPosition
}: {
  readonly fillChar: string
  readonly fillPosition: MStringFillPosition.Type
}) => MTypes.StringTransformer

trimEnd

Removes characters from the end of the string.

  • Only single charToRemove character is supported.
  • Removes all trailing instances of the character.
  • Returns string unchanged if last character doesn’t match.
  • Use for custom right-trimming beyond whitespace.

Example (Trim end character)

import * as MString from "@parischap/effect-lib/String/String"

const result = MString.trimEnd("!")("hello!!!")
console.log(result) // "hello"

Signature

export declare const trimEnd: (charToRemove: string) => MTypes.StringTransformer

trimStart

Removes characters from the start of the string.

  • Only single charToRemove character is supported.
  • Removes all leading instances of the character.
  • Returns string unchanged if first character doesn’t match.
  • Use for custom left-trimming beyond whitespace.

Example (Trim start character)

import * as MString from "@parischap/effect-lib/String/String"

const result = MString.trimStart("*")("***hello***")
console.log(result) // "hello***"

Signature

export declare const trimStart: (charToRemove: string) => MTypes.StringTransformer