Source Edit

The system module defines several common functions for working with strings, such as:

  • $ for converting other data-types to strings
  • & for string concatenation
  • add for adding a new character or a string to the existing one
  • in (alias for contains) and notin for checking if a character is in a string

This module builds upon that, providing additional functionality in form of procedures, iterators and templates for strings.

Example:

  1. import std/strutils
  2. let
  3. numbers = @[867, 5309]
  4. multiLineString = "first line\nsecond line\nthird line"
  5. let jenny = numbers.join("-")
  6. assert jenny == "867-5309"
  7. assert splitLines(multiLineString) ==
  8. @["first line", "second line", "third line"]
  9. assert split(multiLineString) == @["first", "line", "second",
  10. "line", "third", "line"]
  11. assert indent(multiLineString, 4) ==
  12. " first line\n second line\n third line"
  13. assert 'z'.repeat(5) == "zzzzz"

The chaining of functions is possible thanks to the method call syntax:

Example:

  1. import std/strutils
  2. from std/sequtils import map
  3. let jenny = "867-5309"
  4. assert jenny.split('-').map(parseInt) == @[867, 5309]
  5. assert "Beetlejuice".indent(1).repeat(3).strip ==
  6. "Beetlejuice Beetlejuice Beetlejuice"

This module is available for the JavaScript target.


See also:

  • strformat module for string interpolation and formatting
  • unicode module for Unicode UTF-8 handling
  • sequtils module for operations on container types (including strings)
  • parsecsv module for a high-performance CSV parser
  • parseutils module for lower-level parsing of tokens, numbers, identifiers, etc.
  • parseopt module for command-line parsing
  • pegs module for PEG (Parsing Expression Grammar) support
  • strtabs module for efficient hash tables (dictionaries, in some programming languages) mapping from strings to strings
  • ropes module for rope data type, which can represent very long strings efficiently
  • re module for regular expression (regex) support
  • strscans for scanf and scanp macros, which offer easier substring extraction than regular expressions

Imports

parseutils, math, algorithm, enumutils, unicode, since, jsutils, strimpl

Types

  1. BinaryPrefixMode = enum
  2. bpIEC, bpColloquial

The different names for binary prefixes. Source Edit

  1. FloatFormatMode = enum
  2. ffDefault, ## use the shorter floating point notation
  3. ffDecimal, ## use decimal floating point notation
  4. ffScientific ## use scientific notation (using `e` character)

The different modes of floating point formatting. Source Edit

  1. SkipTable = array[char, int]

Character table for efficient substring search. Source Edit

Consts

  1. AllChars = {'\x00'..'\xFF'}

A set with all the possible characters.

Not very useful by its own, you can use it to create inverted sets to make the find func find invalid characters in strings. Example:

  1. let invalid = AllChars - Digits
  2. doAssert "01234".find(invalid) == -1
  3. doAssert "01A34".find(invalid) == 2

Source Edit

  1. Digits = {'0'..'9'}

The set of digits. Source Edit

  1. HexDigits = {'0'..'9', 'A'..'F', 'a'..'f'}

The set of hexadecimal digits. Source Edit

  1. IdentChars = {'a'..'z', 'A'..'Z', '0'..'9', '_'}

The set of characters an identifier can consist of. Source Edit

  1. IdentStartChars = {'a'..'z', 'A'..'Z', '_'}

The set of characters an identifier can start with. Source Edit

  1. Letters = {'A'..'Z', 'a'..'z'}

The set of letters. Source Edit

  1. LowercaseLetters = {'a'..'z'}

The set of lowercase ASCII letters. Source Edit

  1. Newlines = {'\r', '\n'}

The set of characters a newline terminator can start with (carriage return, line feed). Source Edit

  1. PrintableChars = {'\t'..'\r', ' '..'~'}

The set of all printable ASCII characters (letters, digits, whitespace, and punctuation characters). Source Edit

  1. PunctuationChars = {'!'..'/', ':'..'@', '['..'`', '{'..'~'}

The set of all ASCII punctuation characters. Source Edit

  1. UppercaseLetters = {'A'..'Z'}

The set of uppercase ASCII letters. Source Edit

  1. Whitespace = {' ', '\t', '\v', '\r', '\n', '\f'}

All the characters that count as whitespace (space, tab, vertical tab, carriage return, new line, form feed). Source Edit

Procs

  1. func `%`(formatstr, a: string): string {....gcsafe, extern: "nsuFormatSingleElem",
  2. raises: [ValueError], tags: [], forbids: [].}

This is the same as formatstr % [a] (see % func). Source Edit

  1. func `%`(formatstr: string; a: openArray[string]): string {....gcsafe,
  2. extern: "nsuFormatOpenArray", raises: [ValueError], tags: [], forbids: [].}

Interpolates a format string with the values from a.

The substitution operator performs string substitutions in formatstr and returns a modified formatstr. This is often called string interpolation.

This is best explained by an example:

  1. "$1 eats $2." % ["The cat", "fish"]

Results in:

  1. "The cat eats fish."

The substitution variables (the thing after the $) are enumerated from 1 to a.len. To produce a verbatim $, use $$. The notation $# can be used to refer to the next substitution variable:

  1. "$# eats $#." % ["The cat", "fish"]

Substitution variables can also be words (that is [A-Za-z_]+[A-Za-z0-9_]*) in which case the arguments in a with even indices are keys and with odd indices are the corresponding values. An example:

  1. "$animal eats $food." % ["animal", "The cat", "food", "fish"]

Results in:

  1. "The cat eats fish."

The variables are compared with cmpIgnoreStyle. ValueError is raised if an ill-formed format string has been passed to the % operator.

See also:

Source Edit

  1. func abbrev(s: string; possibilities: openArray[string]): int {....raises: [],
  2. tags: [], forbids: [].}

Returns the index of the first item in possibilities which starts with s, if not ambiguous.

Returns -1 if no item has been found and -2 if multiple items match.

Example:

  1. doAssert abbrev("fac", ["college", "faculty", "industry"]) == 1
  2. doAssert abbrev("foo", ["college", "faculty", "industry"]) == -1 # Not found
  3. doAssert abbrev("fac", ["college", "faculty", "faculties"]) == -2 # Ambiguous
  4. doAssert abbrev("college", ["college", "colleges", "industry"]) == 0

Source Edit

  1. func addf(s: var string; formatstr: string; a: varargs[string, `$`]) {....gcsafe,
  2. extern: "nsuAddf", raises: [ValueError], tags: [], forbids: [].}

The same as add(s, formatstr % a), but more efficient. Source Edit

  1. func addSep(dest: var string; sep = ", "; startLen: Natural = 0) {.inline,
  2. ...raises: [], tags: [], forbids: [].}

Adds a separator to dest only if its length is bigger than startLen.

A shorthand for:

  1. if dest.len > startLen: add(dest, sep)

This is often useful for generating some code where the items need to be separated by sep. sep is only added if dest is longer than startLen. The following example creates a string describing an array of integers.

Example:

  1. var arr = "["
  2. for x in items([2, 3, 5, 7, 11]):
  3. addSep(arr, startLen = len("["))
  4. add(arr, $x)
  5. add(arr, "]")
  6. doAssert arr == "[2, 3, 5, 7, 11]"

Source Edit

  1. func align(s: string; count: Natural; padding = ' '): string {....gcsafe,
  2. extern: "nsuAlignString", raises: [], tags: [], forbids: [].}

Aligns a string s with padding, so that it is of length count.

padding characters (by default spaces) are added before s resulting in right alignment. If s.len >= count, no spaces are added and s is returned unchanged. If you need to left align a string use the alignLeft func.

See also:

Example:

  1. assert align("abc", 4) == " abc"
  2. assert align("a", 0) == "a"
  3. assert align("1232", 6) == " 1232"
  4. assert align("1232", 6, '#') == "##1232"

Source Edit

  1. func alignLeft(s: string; count: Natural; padding = ' '): string {....raises: [],
  2. tags: [], forbids: [].}

Left-Aligns a string s with padding, so that it is of length count.

padding characters (by default spaces) are added after s resulting in left alignment. If s.len >= count, no spaces are added and s is returned unchanged. If you need to right align a string use the align func.

See also:

Example:

  1. assert alignLeft("abc", 4) == "abc "
  2. assert alignLeft("a", 0) == "a"
  3. assert alignLeft("1232", 6) == "1232 "
  4. assert alignLeft("1232", 6, '#') == "1232##"

Source Edit

  1. func allCharsInSet(s: string; theSet: set[char]): bool {....raises: [], tags: [],
  2. forbids: [].}

Returns true if every character of s is in the set theSet.

Example:

  1. doAssert allCharsInSet("aeea", {'a', 'e'}) == true
  2. doAssert allCharsInSet("", {'a', 'e'}) == true

Source Edit

  1. func capitalizeAscii(s: string): string {....gcsafe, extern: "nsuCapitalizeAscii",
  2. raises: [], tags: [], forbids: [].}

Converts the first character of string s into upper case.

This works only for the letters A-Z. Use Unicode module for UTF-8 support.

See also:

Example:

  1. doAssert capitalizeAscii("foo") == "Foo"
  2. doAssert capitalizeAscii("-bar") == "-bar"

Source Edit

  1. func center(s: string; width: int; fillChar: char = ' '): string {....gcsafe,
  2. extern: "nsuCenterString", raises: [], tags: [], forbids: [].}

Return the contents of s centered in a string width long using fillChar (default: space) as padding.

The original string is returned if width is less than or equal to s.len.

See also:

Example:

  1. let a = "foo"
  2. doAssert a.center(2) == "foo"
  3. doAssert a.center(5) == " foo "
  4. doAssert a.center(6) == " foo "

Source Edit

  1. func cmpIgnoreCase(a, b: string): int {....gcsafe, extern: "nsuCmpIgnoreCase",
  2. raises: [], tags: [], forbids: [].}

Compares two strings in a case insensitive manner. Returns:

0 if a == b
< 0 if a < b
> 0 if a > b

Example:

  1. doAssert cmpIgnoreCase("FooBar", "foobar") == 0
  2. doAssert cmpIgnoreCase("bar", "Foo") < 0
  3. doAssert cmpIgnoreCase("Foo5", "foo4") > 0

Source Edit

  1. func cmpIgnoreStyle(a, b: string): int {....gcsafe, extern: "nsuCmpIgnoreStyle",
  2. raises: [], tags: [], forbids: [].}

Semantically the same as cmp(normalize(a), normalize(b)). It is just optimized to not allocate temporary strings. This should NOT be used to compare Nim identifier names. Use macros.eqIdent for that.

Returns:

0 if a == b
< 0 if a < b
> 0 if a > b

Example:

  1. doAssert cmpIgnoreStyle("foo_bar", "FooBar") == 0
  2. doAssert cmpIgnoreStyle("foo_bar_5", "FooBar4") > 0

Source Edit

  1. func contains(s, sub: string): bool {....raises: [], tags: [], forbids: [].}

Same as find(s, sub) >= 0.

See also:

Source Edit

  1. func contains(s: string; chars: set[char]): bool {....raises: [], tags: [],
  2. forbids: [].}

Same as find(s, chars) >= 0.

See also:

Source Edit

  1. func continuesWith(s, substr: string; start: Natural): bool {....gcsafe,
  2. extern: "nsuContinuesWith", raises: [], tags: [], forbids: [].}

Returns true if s continues with substr at position start.

If substr == “” true is returned.

See also:

Example:

  1. let a = "abracadabra"
  2. doAssert a.continuesWith("ca", 4) == true
  3. doAssert a.continuesWith("ca", 5) == false
  4. doAssert a.continuesWith("dab", 6) == true

Source Edit

  1. func count(s: string; sub: char): int {....gcsafe, extern: "nsuCountChar",
  2. raises: [], tags: [], forbids: [].}

Counts the occurrences of the character sub in the string s.

See also:

Source Edit

  1. func count(s: string; sub: string; overlapping: bool = false): int {....gcsafe,
  2. extern: "nsuCountString", raises: [], tags: [], forbids: [].}

Counts the occurrences of a substring sub in the string s. Overlapping occurrences of sub only count when overlapping is set to true (default: false).

See also:

Source Edit

  1. func count(s: string; subs: set[char]): int {....gcsafe, extern: "nsuCountCharSet",
  2. raises: [], tags: [], forbids: [].}

Counts the occurrences of the group of character subs in the string s.

See also:

Source Edit

  1. func countLines(s: string): int {....gcsafe, extern: "nsuCountLines", raises: [],
  2. tags: [], forbids: [].}

Returns the number of lines in the string s.

This is the same as len(splitLines(s)), but much more efficient because it doesn’t modify the string creating temporary objects. Every character literal newline combination (CR, LF, CR-LF) is supported.

In this context, a line is any string separated by a newline combination. A line can be an empty string.

See also:

Example:

  1. doAssert countLines("First line\l and second line.") == 2

Source Edit

  1. func dedent(s: string; count: Natural = indentation(s)): string {....gcsafe,
  2. extern: "nsuDedent", raises: [], tags: [], forbids: [].}

Unindents each line in s by count amount of padding. The only difference between this and the unindent func is that this by default only cuts off the amount of indentation that all lines of s share as opposed to all indentation. It only supports spaces as padding.

Note: This does not preserve the new line characters used in s.

See also:

Example:

  1. let x = """
  2. Hello
  3. There
  4. """.dedent()
  5. doAssert x == "Hello\n There\n"

Source Edit

  1. func delete(s: var string; first, last: int) {....gcsafe, extern: "nsuDelete",
  2. deprecated: "use `delete(s, first..last)`", raises: [], tags: [],
  3. forbids: [].}

Deprecated: use `delete(s, first..last)`

Deletes in s the characters at positions first .. last (both ends included).

Example: cmd: —warning:deprecated:off

  1. var a = "abracadabra"
  2. a.delete(4, 5)
  3. doAssert a == "abradabra"
  4. a.delete(1, 6)
  5. doAssert a == "ara"
  6. a.delete(2, 999)
  7. doAssert a == "ar"

Source Edit

  1. func delete(s: var string; slice: Slice[int]) {....raises: [], tags: [],
  2. forbids: [].}

Deletes the items s[slice], raising IndexDefect if the slice contains elements out of range.

This operation moves all elements after s[slice] in linear time, and is the string analog to sequtils.delete.

Example:

  1. var a = "abcde"
  2. doAssertRaises(IndexDefect): a.delete(4..5)
  3. assert a == "abcde"
  4. a.delete(4..4)
  5. assert a == "abcd"
  6. a.delete(1..2)
  7. assert a == "ad"
  8. a.delete(1..<1) # empty slice
  9. assert a == "ad"

Source Edit

  1. func endsWith(s, suffix: string): bool {....gcsafe, extern: "nsuEndsWith",
  2. raises: [], tags: [], forbids: [].}

Returns true if s ends with suffix.

If suffix == “” true is returned.

See also:

Example:

  1. let a = "abracadabra"
  2. doAssert a.endsWith("abra") == true
  3. doAssert a.endsWith("dab") == false

Source Edit

  1. func endsWith(s: string; suffix: char): bool {.inline, ...raises: [], tags: [],
  2. forbids: [].}

Returns true if s ends with suffix.

See also:

Example:

  1. let a = "abracadabra"
  2. doAssert a.endsWith('a') == true
  3. doAssert a.endsWith('b') == false

Source Edit

  1. func escape(s: string; prefix = "\""; suffix = "\""): string {....gcsafe,
  2. extern: "nsuEscape", raises: [], tags: [], forbids: [].}

Escapes a string s.

Note: The escaping scheme is different from system.addEscapedChar.

  • replaces ‘\0’..’\31’ and ‘\127’..’\255’ by \xHH where HH is its hexadecimal value
  • replaces \ by \\
  • replaces ‘ by \‘
  • replaces “ by \“

The resulting string is prefixed with prefix and suffixed with suffix. Both may be empty strings.

See also:

Source Edit

  1. func find(a: SkipTable; s, sub: string; start: Natural = 0; last = -1): int {.
  2. ...gcsafe, extern: "nsuFindStrA", raises: [], tags: [], forbids: [].}

Searches for sub in s inside range start..last using preprocessed table a. If last is unspecified, it defaults to s.high (the last element).

Searching is case-sensitive. If sub is not in s, -1 is returned.

See also:

Source Edit

  1. func find(s, sub: string; start: Natural = 0; last = -1): int {....gcsafe,
  2. extern: "nsuFindStr", raises: [], tags: [], forbids: [].}

Searches for sub in s inside range start..last (both ends included). If last is unspecified or negative, it defaults to s.high (the last element).

Searching is case-sensitive. If sub is not in s, -1 is returned. Otherwise the index returned is relative to s[0], not start. Subtract start from the result for a start-origin index.

See also:

Source Edit

  1. func find(s: string; chars: set[char]; start: Natural = 0; last = -1): int {.
  2. ...gcsafe, extern: "nsuFindCharSet", raises: [], tags: [], forbids: [].}

Searches for chars in s inside range start..last (both ends included). If last is unspecified or negative, it defaults to s.high (the last element).

If s contains none of the characters in chars, -1 is returned. Otherwise the index returned is relative to s[0], not start. Subtract start from the result for a start-origin index.

See also:

Source Edit

  1. func find(s: string; sub: char; start: Natural = 0; last = -1): int {....gcsafe,
  2. extern: "nsuFindChar", raises: [], tags: [], forbids: [].}

Searches for sub in s inside range start..last (both ends included). If last is unspecified or negative, it defaults to s.high (the last element).

Searching is case-sensitive. If sub is not in s, -1 is returned. Otherwise the index returned is relative to s[0], not start. Subtract start from the result for a start-origin index.

See also:

Source Edit

  1. func format(formatstr: string; a: varargs[string, `$`]): string {....gcsafe,
  2. extern: "nsuFormatVarargs", raises: [ValueError], tags: [], forbids: [].}

This is the same as formatstr % a (see % func) except that it supports auto stringification.

See also:

Source Edit

  1. func formatBiggestFloat(f: BiggestFloat; format: FloatFormatMode = ffDefault;
  2. precision: range[-1 .. 32] = 16; decimalSep = '.'): string {.
  3. ...gcsafe, extern: "nsu$1", raises: [], tags: [], forbids: [].}

Converts a floating point value f to a string.

If format == ffDecimal then precision is the number of digits to be printed after the decimal point. If format == ffScientific then precision is the maximum number of significant digits to be printed. precision’s default value is the maximum number of meaningful digits after the decimal point for Nim’s biggestFloat type.

If precision == -1, it tries to format it nicely.

Example:

  1. let x = 123.456
  2. doAssert x.formatBiggestFloat() == "123.4560000000000"
  3. doAssert x.formatBiggestFloat(ffDecimal, 4) == "123.4560"
  4. doAssert x.formatBiggestFloat(ffScientific, 2) == "1.23e+02"

Source Edit

  1. func formatEng(f: BiggestFloat; precision: range[0 .. 32] = 10;
  2. trim: bool = true; siPrefix: bool = false; unit: string = "";
  3. decimalSep = '.'; useUnitSpace = false): string {....raises: [],
  4. tags: [], forbids: [].}

Converts a floating point value f to a string using engineering notation.

Numbers in of the range -1000.0<f<1000.0 will be formatted without an exponent. Numbers outside of this range will be formatted as a significand in the range -1000.0<f<1000.0 and an exponent that will always be an integer multiple of 3, corresponding with the SI prefix scale k, M, G, T etc for numbers with an absolute value greater than 1 and m, μ, n, p etc for numbers with an absolute value less than 1.

The default configuration (trim=true and precision=10) shows the shortest form that precisely (up to a maximum of 10 decimal places) displays the value. For example, 4.100000 will be displayed as 4.1 (which is mathematically identical) whereas 4.1000003 will be displayed as 4.1000003.

If trim is set to true, trailing zeros will be removed; if false, the number of digits specified by precision will always be shown.

precision can be used to set the number of digits to be shown after the decimal point or (if trim is true) the maximum number of digits to be shown.

  1. formatEng(0, 2, trim=false) == "0.00"
  2. formatEng(0, 2) == "0"
  3. formatEng(0.053, 0) == "53e-3"
  4. formatEng(52731234, 2) == "52.73e6"
  5. formatEng(-52731234, 2) == "-52.73e6"

If siPrefix is set to true, the number will be displayed with the SI prefix corresponding to the exponent. For example 4100 will be displayed as “4.1 k” instead of “4.1e3”. Note that u is used for micro- in place of the greek letter mu (μ) as per ISO 2955. Numbers with an absolute value outside of the range 1e-18<f<1000e18 (1a<f<1000E) will be displayed with an exponent rather than an SI prefix, regardless of whether siPrefix is true.

If useUnitSpace is true, the provided unit will be appended to the string (with a space as required by the SI standard). This behaviour is slightly different to appending the unit to the result as the location of the space is altered depending on whether there is an exponent.

  1. formatEng(4100, siPrefix=true, unit="V") == "4.1 kV"
  2. formatEng(4.1, siPrefix=true, unit="V") == "4.1 V"
  3. formatEng(4.1, siPrefix=true) == "4.1" # Note lack of space
  4. formatEng(4100, siPrefix=true) == "4.1 k"
  5. formatEng(4.1, siPrefix=true, unit="") == "4.1 " # Space with unit=""
  6. formatEng(4100, siPrefix=true, unit="") == "4.1 k"
  7. formatEng(4100) == "4.1e3"
  8. formatEng(4100, unit="V") == "4.1e3 V"
  9. formatEng(4100, unit="", useUnitSpace=true) == "4.1e3 " # Space with useUnitSpace=true

decimalSep is used as the decimal separator.

See also:

Source Edit

  1. func formatFloat(f: float; format: FloatFormatMode = ffDefault;
  2. precision: range[-1 .. 32] = 16; decimalSep = '.'): string {.
  3. ...gcsafe, extern: "nsu$1", raises: [], tags: [], forbids: [].}

Converts a floating point value f to a string.

If format == ffDecimal then precision is the number of digits to be printed after the decimal point. If format == ffScientific then precision is the maximum number of significant digits to be printed. precision’s default value is the maximum number of meaningful digits after the decimal point for Nim’s float type.

If precision == -1, it tries to format it nicely.

Example:

  1. let x = 123.456
  2. doAssert x.formatFloat() == "123.4560000000000"
  3. doAssert x.formatFloat(ffDecimal, 4) == "123.4560"
  4. doAssert x.formatFloat(ffScientific, 2) == "1.23e+02"

Source Edit

  1. func formatSize(bytes: int64; decimalSep = '.'; prefix = bpIEC;
  2. includeSpace = false): string {....raises: [], tags: [],
  3. forbids: [].}

Rounds and formats bytes.

By default, uses the IEC/ISO standard binary prefixes, so 1024 will be formatted as 1KiB. Set prefix to bpColloquial to use the colloquial names from the SI standard (e.g. k for 1000 being reused as 1024).

includeSpace can be set to true to include the (SI preferred) space between the number and the unit (e.g. 1 KiB).

See also:

Example:

  1. doAssert formatSize((1'i64 shl 31) + (300'i64 shl 20)) == "2.293GiB"
  2. doAssert formatSize((2.234*1024*1024).int) == "2.234MiB"
  3. doAssert formatSize(4096, includeSpace = true) == "4 KiB"
  4. doAssert formatSize(4096, prefix = bpColloquial, includeSpace = true) == "4 kB"
  5. doAssert formatSize(4096) == "4KiB"
  6. doAssert formatSize(5_378_934, prefix = bpColloquial, decimalSep = ',') == "5,13MB"

Source Edit

  1. func fromBin[T: SomeInteger](s: string): T

Parses a binary integer value from a string s.

If s is not a valid binary integer, ValueError is raised. s can have one of the following optional prefixes: 0b, 0B. Underscores within s are ignored.

Does not check for overflow. If the value represented by s is too big to fit into a return type, only the value of the rightmost binary digits of s is returned without producing an error.

Example:

  1. let s = "0b_0100_1000_1000_1000_1110_1110_1001_1001"
  2. doAssert fromBin[int](s) == 1216933529
  3. doAssert fromBin[int8](s) == 0b1001_1001'i8
  4. doAssert fromBin[int8](s) == -103'i8
  5. doAssert fromBin[uint8](s) == 153
  6. doAssert s.fromBin[:int16] == 0b1110_1110_1001_1001'i16
  7. doAssert s.fromBin[:uint64] == 1216933529'u64

Source Edit

  1. func fromHex[T: SomeInteger](s: string): T

Parses a hex integer value from a string s.

If s is not a valid hex integer, ValueError is raised. s can have one of the following optional prefixes: 0x, 0X, #. Underscores within s are ignored.

Does not check for overflow. If the value represented by s is too big to fit into a return type, only the value of the rightmost hex digits of s is returned without producing an error.

Example:

  1. let s = "0x_1235_8df6"
  2. doAssert fromHex[int](s) == 305499638
  3. doAssert fromHex[int8](s) == 0xf6'i8
  4. doAssert fromHex[int8](s) == -10'i8
  5. doAssert fromHex[uint8](s) == 246'u8
  6. doAssert s.fromHex[:int16] == -29194'i16
  7. doAssert s.fromHex[:uint64] == 305499638'u64

Source Edit

  1. func fromOct[T: SomeInteger](s: string): T

Parses an octal integer value from a string s.

If s is not a valid octal integer, ValueError is raised. s can have one of the following optional prefixes: 0o, 0O. Underscores within s are ignored.

Does not check for overflow. If the value represented by s is too big to fit into a return type, only the value of the rightmost octal digits of s is returned without producing an error.

Example:

  1. let s = "0o_123_456_777"
  2. doAssert fromOct[int](s) == 21913087
  3. doAssert fromOct[int8](s) == 0o377'i8
  4. doAssert fromOct[int8](s) == -1'i8
  5. doAssert fromOct[uint8](s) == 255'u8
  6. doAssert s.fromOct[:int16] == 24063'i16
  7. doAssert s.fromOct[:uint64] == 21913087'u64

Source Edit

  1. func indent(s: string; count: Natural; padding: string = " "): string {....gcsafe,
  2. extern: "nsuIndent", raises: [], tags: [], forbids: [].}

Indents each line in s by count amount of padding.

Note: This does not preserve the new line characters used in s.

See also:

Example:

  1. doAssert indent("First line\c\l and second line.", 2) ==
  2. " First line\l and second line."

Source Edit

  1. func indentation(s: string): Natural {....raises: [], tags: [], forbids: [].}

Returns the amount of indentation all lines of s have in common, ignoring lines that consist only of whitespace. Source Edit

  1. func initSkipTable(a: var SkipTable; sub: string) {....gcsafe,
  2. extern: "nsuInitSkipTable", raises: [], tags: [], forbids: [].}

Initializes table a for efficient search of substring sub.

See also:

Source Edit

  1. func initSkipTable(sub: string): SkipTable {.noinit, ...gcsafe,
  2. extern: "nsuInitNewSkipTable", raises: [], tags: [], forbids: [].}

Returns a new table initialized for sub.

See also:

Source Edit

  1. func insertSep(s: string; sep = '_'; digits = 3): string {....gcsafe,
  2. extern: "nsuInsertSep", raises: [], tags: [], forbids: [].}

Inserts the separator sep after digits characters (default: 3) from right to left.

Even though the algorithm works with any string s, it is only useful if s contains a number.

Example:

  1. doAssert insertSep("1000000") == "1_000_000"

Source Edit

  1. func intToStr(x: int; minchars: Positive = 1): string {....gcsafe,
  2. extern: "nsuIntToStr", raises: [], tags: [], forbids: [].}

Converts x to its decimal representation.

The resulting string will be minimally minchars characters long. This is achieved by adding leading zeros.

Example:

  1. doAssert intToStr(1984) == "1984"
  2. doAssert intToStr(1984, 6) == "001984"

Source Edit

  1. func isAlphaAscii(c: char): bool {....gcsafe, extern: "nsuIsAlphaAsciiChar",
  2. raises: [], tags: [], forbids: [].}

Checks whether or not character c is alphabetical.

This checks a-z, A-Z ASCII characters only. Use Unicode module for UTF-8 support.

Example:

  1. doAssert isAlphaAscii('e') == true
  2. doAssert isAlphaAscii('E') == true
  3. doAssert isAlphaAscii('8') == false

Source Edit

  1. func isAlphaNumeric(c: char): bool {....gcsafe, extern: "nsuIsAlphaNumericChar",
  2. raises: [], tags: [], forbids: [].}

Checks whether or not c is alphanumeric.

This checks a-z, A-Z, 0-9 ASCII characters only.

Example:

  1. doAssert isAlphaNumeric('n') == true
  2. doAssert isAlphaNumeric('8') == true
  3. doAssert isAlphaNumeric(' ') == false

Source Edit

  1. func isDigit(c: char): bool {....gcsafe, extern: "nsuIsDigitChar", raises: [],
  2. tags: [], forbids: [].}

Checks whether or not c is a number.

This checks 0-9 ASCII characters only.

Example:

  1. doAssert isDigit('n') == false
  2. doAssert isDigit('8') == true

Source Edit

  1. func isEmptyOrWhitespace(s: string): bool {....gcsafe,
  2. extern: "nsuIsEmptyOrWhitespace", raises: [], tags: [], forbids: [].}

Checks if s is empty or consists entirely of whitespace characters. Source Edit

  1. func isLowerAscii(c: char): bool {....gcsafe, extern: "nsuIsLowerAsciiChar",
  2. raises: [], tags: [], forbids: [].}

Checks whether or not c is a lower case character.

This checks ASCII characters only. Use Unicode module for UTF-8 support.

See also:

Example:

  1. doAssert isLowerAscii('e') == true
  2. doAssert isLowerAscii('E') == false
  3. doAssert isLowerAscii('7') == false

Source Edit

  1. func isSpaceAscii(c: char): bool {....gcsafe, extern: "nsuIsSpaceAsciiChar",
  2. raises: [], tags: [], forbids: [].}

Checks whether or not c is a whitespace character.

Example:

  1. doAssert isSpaceAscii('n') == false
  2. doAssert isSpaceAscii(' ') == true
  3. doAssert isSpaceAscii('\t') == true

Source Edit

  1. func isUpperAscii(c: char): bool {....gcsafe, extern: "nsuIsUpperAsciiChar",
  2. raises: [], tags: [], forbids: [].}

Checks whether or not c is an upper case character.

This checks ASCII characters only. Use Unicode module for UTF-8 support.

See also:

Example:

  1. doAssert isUpperAscii('e') == false
  2. doAssert isUpperAscii('E') == true
  3. doAssert isUpperAscii('7') == false

Source Edit

  1. func join(a: openArray[string]; sep: string = ""): string {....gcsafe,
  2. extern: "nsuJoinSep", raises: [], tags: [], forbids: [].}

Concatenates all strings in the container a, separating them with sep.

Example:

  1. doAssert join(["A", "B", "Conclusion"], " -> ") == "A -> B -> Conclusion"

Source Edit

  1. proc join[T: not string](a: openArray[T]; sep: string = ""): string

Converts all elements in the container a to strings using $, and concatenates them with sep.

Example:

  1. doAssert join([1, 2, 3], " -> ") == "1 -> 2 -> 3"

Source Edit

  1. func multiReplace(s: string; replacements: varargs[(string, string)]): string {.
  2. ...raises: [], tags: [], forbids: [].}

Same as replace, but specialized for doing multiple replacements in a single pass through the input string.

multiReplace performs all replacements in a single pass, this means it can be used to swap the occurrences of “a” and “b”, for instance.

If the resulting string is not longer than the original input string, only a single memory allocation is required.

The order of the replacements does matter. Earlier replacements are preferred over later replacements in the argument list.

Source Edit

  1. func nimIdentNormalize(s: string): string {....raises: [], tags: [], forbids: [].}

Normalizes the string s as a Nim identifier.

That means to convert to lower case and remove any ‘_‘ on all characters except first one.

Warning: Backticks (`) are not handled: they remain as is and spaces are preserved. See nimIdentBackticksNormalize for an alternative approach.

Example:

  1. doAssert nimIdentNormalize("Foo_bar") == "Foobar"

Source Edit

  1. func normalize(s: string): string {....gcsafe, extern: "nsuNormalize", raises: [],
  2. tags: [], forbids: [].}

Normalizes the string s.

That means to convert it to lower case and remove any ‘_‘. This should NOT be used to normalize Nim identifier names.

See also:

Example:

  1. doAssert normalize("Foo_bar") == "foobar"
  2. doAssert normalize("Foo Bar") == "foo bar"

Source Edit

  1. func parseBiggestInt(s: string): BiggestInt {....gcsafe,
  2. extern: "nsuParseBiggestInt", raises: [ValueError], tags: [], forbids: [].}

Parses a decimal integer value contained in s.

If s is not a valid integer, ValueError is raised.

Source Edit

  1. func parseBiggestUInt(s: string): BiggestUInt {....gcsafe,
  2. extern: "nsuParseBiggestUInt", raises: [ValueError], tags: [], forbids: [].}

Parses a decimal unsigned integer value contained in s.

If s is not a valid integer, ValueError is raised.

Source Edit

  1. func parseBinInt(s: string): int {....gcsafe, extern: "nsuParseBinInt",
  2. raises: [ValueError], tags: [], forbids: [].}

Parses a binary integer value contained in s.

If s is not a valid binary integer, ValueError is raised. s can have one of the following optional prefixes: 0b, 0B. Underscores within s are ignored.

Example:

  1. let
  2. a = "0b11_0101"
  3. b = "111"
  4. doAssert a.parseBinInt() == 53
  5. doAssert b.parseBinInt() == 7

Source Edit

  1. func parseBool(s: string): bool {....raises: [ValueError], tags: [], forbids: [].}

Parses a value into a bool.

If s is one of the following values: y, yes, true, 1, on, then returns true. If s is one of the following values: n, no, false, 0, off, then returns false. If s is something else a ValueError exception is raised.

Example:

  1. let a = "n"
  2. doAssert parseBool(a) == false

Source Edit

  1. func parseEnum[T: enum](s: string): T

Parses an enum T. This errors at compile time, if the given enum type contains multiple fields with the same string value.

Raises ValueError for an invalid value in s. The comparison is done in a style insensitive way.

Example:

  1. type
  2. MyEnum = enum
  3. first = "1st",
  4. second,
  5. third = "3rd"
  6. doAssert parseEnum[MyEnum]("1_st") == first
  7. doAssert parseEnum[MyEnum]("second") == second
  8. doAssertRaises(ValueError):
  9. echo parseEnum[MyEnum]("third")

Source Edit

  1. func parseEnum[T: enum](s: string; default: T): T

Parses an enum T. This errors at compile time, if the given enum type contains multiple fields with the same string value.

Uses default for an invalid value in s. The comparison is done in a style insensitive way.

Example:

  1. type
  2. MyEnum = enum
  3. first = "1st",
  4. second,
  5. third = "3rd"
  6. doAssert parseEnum[MyEnum]("1_st") == first
  7. doAssert parseEnum[MyEnum]("second") == second
  8. doAssert parseEnum[MyEnum]("last", third) == third

Source Edit

  1. func parseFloat(s: string): float {....gcsafe, extern: "nsuParseFloat",
  2. raises: [ValueError], tags: [], forbids: [].}

Parses a decimal floating point value contained in s.

If s is not a valid floating point number, ValueError is raised. NAN, INF, -INF are also supported (case insensitive comparison).

Example:

  1. doAssert parseFloat("3.14") == 3.14
  2. doAssert parseFloat("inf") == 1.0/0

Source Edit

  1. func parseHexInt(s: string): int {....gcsafe, extern: "nsuParseHexInt",
  2. raises: [ValueError], tags: [], forbids: [].}

Parses a hexadecimal integer value contained in s.

If s is not a valid hex integer, ValueError is raised. s can have one of the following optional prefixes: 0x, 0X, #. Underscores within s are ignored.

Source Edit

  1. func parseHexStr(s: string): string {....gcsafe, extern: "nsuParseHexStr",
  2. raises: [ValueError], tags: [],
  3. forbids: [].}

Converts hex-encoded string to byte string, e.g.:

Raises ValueError for an invalid hex values. The comparison is case-insensitive.

See also:

Example:

  1. let
  2. a = "41"
  3. b = "3161"
  4. c = "00ff"
  5. doAssert parseHexStr(a) == "A"
  6. doAssert parseHexStr(b) == "1a"
  7. doAssert parseHexStr(c) == "\0\255"

Source Edit

  1. func parseInt(s: string): int {....gcsafe, extern: "nsuParseInt",
  2. raises: [ValueError], tags: [], forbids: [].}

Parses a decimal integer value contained in s.

If s is not a valid integer, ValueError is raised.

Example:

  1. doAssert parseInt("-0042") == -42

Source Edit

  1. func parseOctInt(s: string): int {....gcsafe, extern: "nsuParseOctInt",
  2. raises: [ValueError], tags: [], forbids: [].}

Parses an octal integer value contained in s.

If s is not a valid oct integer, ValueError is raised. s can have one of the following optional prefixes: 0o, 0O. Underscores within s are ignored.

Source Edit

  1. func parseUInt(s: string): uint {....gcsafe, extern: "nsuParseUInt",
  2. raises: [ValueError], tags: [], forbids: [].}

Parses a decimal unsigned integer value contained in s.

If s is not a valid integer, ValueError is raised.

Source Edit

  1. func removePrefix(s: var string; c: char) {....gcsafe,
  2. extern: "nsuRemovePrefixChar", raises: [], tags: [], forbids: [].}

Removes all occurrences of a single character (in-place) from the start of a string.

See also:

Example:

  1. var ident = "pControl"
  2. ident.removePrefix('p')
  3. doAssert ident == "Control"

Source Edit

  1. func removePrefix(s: var string; chars: set[char] = Newlines) {....gcsafe,
  2. extern: "nsuRemovePrefixCharSet", raises: [], tags: [], forbids: [].}

Removes all characters from chars from the start of the string s (in-place).

See also:

Example:

  1. var userInput = "\r\n*~Hello World!"
  2. userInput.removePrefix
  3. doAssert userInput == "*~Hello World!"
  4. userInput.removePrefix({'~', '*'})
  5. doAssert userInput == "Hello World!"
  6. var otherInput = "?!?Hello!?!"
  7. otherInput.removePrefix({'!', '?'})
  8. doAssert otherInput == "Hello!?!"

Source Edit

  1. func removePrefix(s: var string; prefix: string) {....gcsafe,
  2. extern: "nsuRemovePrefixString", raises: [], tags: [], forbids: [].}

Remove the first matching prefix (in-place) from a string.

See also:

Example:

  1. var answers = "yesyes"
  2. answers.removePrefix("yes")
  3. doAssert answers == "yes"

Source Edit

  1. func removeSuffix(s: var string; c: char) {....gcsafe,
  2. extern: "nsuRemoveSuffixChar", raises: [], tags: [], forbids: [].}

Removes all occurrences of a single character (in-place) from the end of a string.

See also:

Example:

  1. var table = "users"
  2. table.removeSuffix('s')
  3. doAssert table == "user"
  4. var dots = "Trailing dots......."
  5. dots.removeSuffix('.')
  6. doAssert dots == "Trailing dots"

Source Edit

  1. func removeSuffix(s: var string; chars: set[char] = Newlines) {....gcsafe,
  2. extern: "nsuRemoveSuffixCharSet", raises: [], tags: [], forbids: [].}

Removes all characters from chars from the end of the string s (in-place).

See also:

Example:

  1. var userInput = "Hello World!*~\r\n"
  2. userInput.removeSuffix
  3. doAssert userInput == "Hello World!*~"
  4. userInput.removeSuffix({'~', '*'})
  5. doAssert userInput == "Hello World!"
  6. var otherInput = "Hello!?!"
  7. otherInput.removeSuffix({'!', '?'})
  8. doAssert otherInput == "Hello"

Source Edit

  1. func removeSuffix(s: var string; suffix: string) {....gcsafe,
  2. extern: "nsuRemoveSuffixString", raises: [], tags: [], forbids: [].}

Remove the first matching suffix (in-place) from a string.

See also:

Example:

  1. var answers = "yeses"
  2. answers.removeSuffix("es")
  3. doAssert answers == "yes"

Source Edit

  1. func repeat(c: char; count: Natural): string {....gcsafe, extern: "nsuRepeatChar",
  2. raises: [], tags: [], forbids: [].}

Returns a string of length count consisting only of the character c.

Example:

  1. let a = 'z'
  2. doAssert a.repeat(5) == "zzzzz"

Source Edit

  1. func repeat(s: string; n: Natural): string {....gcsafe, extern: "nsuRepeatStr",
  2. raises: [], tags: [], forbids: [].}

Returns string s concatenated n times.

Example:

  1. doAssert "+ foo +".repeat(3) == "+ foo ++ foo ++ foo +"

Source Edit

  1. func replace(s, sub: string; by = ""): string {....gcsafe, extern: "nsuReplaceStr",
  2. raises: [], tags: [], forbids: [].}

Replaces every occurrence of the string sub in s with the string by.

See also:

Source Edit

  1. func replace(s: string; sub, by: char): string {....gcsafe,
  2. extern: "nsuReplaceChar", raises: [], tags: [], forbids: [].}

Replaces every occurrence of the character sub in s with the character by.

Optimized version of replace for characters.

See also:

Source Edit

  1. func replaceWord(s, sub: string; by = ""): string {....gcsafe,
  2. extern: "nsuReplaceWord", raises: [], tags: [], forbids: [].}

Replaces every occurrence of the string sub in s with the string by.

Each occurrence of sub has to be surrounded by word boundaries (comparable to \b in regular expressions), otherwise it is not replaced.

Source Edit

  1. func rfind(s, sub: string; start: Natural = 0; last = -1): int {....gcsafe,
  2. extern: "nsuRFindStr", raises: [], tags: [], forbids: [].}

Searches for sub in s inside range start..last (both ends included) included) in reverse — starting at high indexes and moving lower to the first character or start. If last is unspecified, it defaults to s.high (the last element).

Searching is case-sensitive. If sub is not in s, -1 is returned. Otherwise the index returned is relative to s[0], not start. Subtract start from the result for a start-origin index.

See also:

Source Edit

  1. func rfind(s: string; chars: set[char]; start: Natural = 0; last = -1): int {.
  2. ...gcsafe, extern: "nsuRFindCharSet", raises: [], tags: [], forbids: [].}

Searches for chars in s inside range start..last (both ends included) in reverse — starting at high indexes and moving lower to the first character or start. If last is unspecified, it defaults to s.high (the last element).

If s contains none of the characters in chars, -1 is returned. Otherwise the index returned is relative to s[0], not start. Subtract start from the result for a start-origin index.

See also:

Source Edit

  1. func rfind(s: string; sub: char; start: Natural = 0; last = -1): int {....gcsafe,
  2. extern: "nsuRFindChar", raises: [], tags: [], forbids: [].}

Searches for sub in s inside range start..last (both ends included) in reverse — starting at high indexes and moving lower to the first character or start. If last is unspecified, it defaults to s.high (the last element).

Searching is case-sensitive. If sub is not in s, -1 is returned. Otherwise the index returned is relative to s[0], not start. Subtract start from the result for a start-origin index.

See also:

Source Edit

  1. func rsplit(s: string; sep: char; maxsplit: int = -1): seq[string] {....gcsafe,
  2. extern: "nsuRSplitChar", raises: [], tags: [], forbids: [].}

The same as the rsplit iterator, but is a func that returns a sequence of substrings in original order.

A possible common use case for rsplit is path manipulation, particularly on systems that don’t use a common delimiter.

For example, if a system had # as a delimiter, you could do the following to get the tail of the path:

  1. var tailSplit = rsplit("Root#Object#Method#Index", '#', maxsplit=1)

Results in tailSplit containing:

  1. @["Root#Object#Method", "Index"]

See also:

Source Edit

  1. func rsplit(s: string; sep: string; maxsplit: int = -1): seq[string] {....gcsafe,
  2. extern: "nsuRSplitString", raises: [], tags: [], forbids: [].}

The same as the rsplit iterator, but is a func that returns a sequence of substrings in original order.

A possible common use case for rsplit is path manipulation, particularly on systems that don’t use a common delimiter.

For example, if a system had # as a delimiter, you could do the following to get the tail of the path:

  1. var tailSplit = rsplit("Root#Object#Method#Index", "#", maxsplit=1)

Results in tailSplit containing:

  1. @["Root#Object#Method", "Index"]

Note: Empty separator string results in returning an original string, following the interpretation “split by no element”.

See also:

Example:

  1. doAssert "a largely spaced sentence".rsplit(" ", maxsplit = 1) == @[
  2. "a largely spaced", "sentence"]
  3. doAssert "a,b,c".rsplit(",") == @["a", "b", "c"]
  4. doAssert "a man a plan a canal panama".rsplit("a ") == @["", "man ",
  5. "plan ", "canal panama"]
  6. doAssert "".rsplit("Elon Musk") == @[""]
  7. doAssert "a largely spaced sentence".rsplit(" ") == @["a", "",
  8. "largely", "", "", "", "spaced", "sentence"]
  9. doAssert "empty sep returns unsplit s".rsplit("") == @["empty sep returns unsplit s"]

Source Edit

  1. func rsplit(s: string; seps: set[char] = Whitespace; maxsplit: int = -1): seq[
  2. string] {....gcsafe, extern: "nsuRSplitCharSet", raises: [], tags: [],
  3. forbids: [].}

The same as the rsplit iterator, but is a func that returns a sequence of substrings in original order.

A possible common use case for rsplit is path manipulation, particularly on systems that don’t use a common delimiter.

For example, if a system had # as a delimiter, you could do the following to get the tail of the path:

  1. var tailSplit = rsplit("Root#Object#Method#Index", {'#'}, maxsplit=1)

Results in tailSplit containing:

  1. @["Root#Object#Method", "Index"]

Note: Empty separator set results in returning an original string, following the interpretation “split by no element”.

See also:

Source Edit

  1. func spaces(n: Natural): string {.inline, ...raises: [], tags: [], forbids: [].}

Returns a string with n space characters. You can use this func to left align strings.

See also:

Example:

  1. let
  2. width = 15
  3. text1 = "Hello user!"
  4. text2 = "This is a very long string"
  5. doAssert text1 & spaces(max(0, width - text1.len)) & "|" ==
  6. "Hello user! |"
  7. doAssert text2 & spaces(max(0, width - text2.len)) & "|" ==
  8. "This is a very long string|"

Source Edit

  1. func split(s: string; sep: char; maxsplit: int = -1): seq[string] {....gcsafe,
  2. extern: "nsuSplitChar", raises: [], tags: [], forbids: [].}

The same as the split iterator (see its documentation), but is a func that returns a sequence of substrings.

See also:

Example:

  1. doAssert "a,b,c".split(',') == @["a", "b", "c"]
  2. doAssert "".split(' ') == @[""]

Source Edit

  1. func split(s: string; sep: string; maxsplit: int = -1): seq[string] {....gcsafe,
  2. extern: "nsuSplitString", raises: [], tags: [], forbids: [].}

Splits the string s into substrings using a string separator.

Substrings are separated by the string sep. This is a wrapper around the split iterator.

Note: Empty separator string results in returning an original string, following the interpretation “split by no element”.

See also:

Example:

  1. doAssert "a,b,c".split(",") == @["a", "b", "c"]
  2. doAssert "a man a plan a canal panama".split("a ") == @["", "man ", "plan ", "canal panama"]
  3. doAssert "".split("Elon Musk") == @[""]
  4. doAssert "a largely spaced sentence".split(" ") == @["a", "", "largely",
  5. "", "", "", "spaced", "sentence"]
  6. doAssert "a largely spaced sentence".split(" ", maxsplit = 1) == @["a", " largely spaced sentence"]
  7. doAssert "empty sep returns unsplit s".split("") == @["empty sep returns unsplit s"]

Source Edit

  1. func split(s: string; seps: set[char] = Whitespace; maxsplit: int = -1): seq[
  2. string] {....gcsafe, extern: "nsuSplitCharSet", raises: [], tags: [],
  3. forbids: [].}

The same as the split iterator (see its documentation), but is a func that returns a sequence of substrings.

Note: Empty separator set results in returning an original string, following the interpretation “split by no element”.

See also:

Example:

  1. doAssert "a,b;c".split({',', ';'}) == @["a", "b", "c"]
  2. doAssert "".split({' '}) == @[""]
  3. doAssert "empty seps return unsplit s".split({}) == @["empty seps return unsplit s"]

Source Edit

  1. func splitLines(s: string; keepEol = false): seq[string] {....gcsafe,
  2. extern: "nsuSplitLines", raises: [], tags: [], forbids: [].}

The same as the splitLines iterator (see its documentation), but is a func that returns a sequence of substrings.

See also:

Source Edit

  1. func splitWhitespace(s: string; maxsplit: int = -1): seq[string] {....gcsafe,
  2. extern: "nsuSplitWhitespace", raises: [], tags: [], forbids: [].}

The same as the splitWhitespace iterator (see its documentation), but is a func that returns a sequence of substrings.

See also:

Source Edit

  1. func startsWith(s, prefix: string): bool {....gcsafe, extern: "nsuStartsWith",
  2. raises: [], tags: [], forbids: [].}

Returns true if s starts with string prefix.

If prefix == “” true is returned.

See also:

Example:

  1. let a = "abracadabra"
  2. doAssert a.startsWith("abra") == true
  3. doAssert a.startsWith("bra") == false

Source Edit

  1. func startsWith(s: string; prefix: char): bool {.inline, ...raises: [], tags: [],
  2. forbids: [].}

Returns true if s starts with character prefix.

See also:

Example:

  1. let a = "abracadabra"
  2. doAssert a.startsWith('a') == true
  3. doAssert a.startsWith('b') == false

Source Edit

  1. func strip(s: string; leading = true; trailing = true;
  2. chars: set[char] = Whitespace): string {....gcsafe, extern: "nsuStrip",
  3. raises: [], tags: [], forbids: [].}

Strips leading or trailing chars (default: whitespace characters) from s and returns the resulting string.

If leading is true (default), leading chars are stripped. If trailing is true (default), trailing chars are stripped. If both are false, the string is returned unchanged.

See also:

Example:

  1. let a = " vhellov "
  2. let b = strip(a)
  3. doAssert b == "vhellov"
  4. doAssert a.strip(leading = false) == " vhellov"
  5. doAssert a.strip(trailing = false) == "vhellov "
  6. doAssert b.strip(chars = {'v'}) == "hello"
  7. doAssert b.strip(leading = false, chars = {'v'}) == "vhello"
  8. let c = "blaXbla"
  9. doAssert c.strip(chars = {'b', 'a'}) == "laXbl"
  10. doAssert c.strip(chars = {'b', 'a', 'l'}) == "X"

Source Edit

  1. func stripLineEnd(s: var string) {....raises: [], tags: [], forbids: [].}

Strips one of these suffixes from s in-place: \r, \n, \r\n, \f, \v (at most once instance). For example, can be useful in conjunction with osproc.execCmdEx. aka: chomp

Example:

  1. var s = "foo\n\n"
  2. s.stripLineEnd
  3. doAssert s == "foo\n"
  4. s = "foo\r\n"
  5. s.stripLineEnd
  6. doAssert s == "foo"

Source Edit

  1. func toBin(x: BiggestInt; len: Positive): string {....gcsafe, extern: "nsuToBin",
  2. raises: [], tags: [], forbids: [].}

Converts x into its binary representation.

The resulting string is always len characters long. No leading 0b prefix is generated.

Example:

  1. let
  2. a = 29
  3. b = 257
  4. doAssert a.toBin(8) == "00011101"
  5. doAssert b.toBin(8) == "00000001"
  6. doAssert b.toBin(9) == "100000001"

Source Edit

  1. func toHex(s: string): string {....gcsafe, raises: [], tags: [], forbids: [].}

Converts a bytes string to its hexadecimal representation.

The output is twice the input long. No prefix like 0x is generated.

See also:

Example:

  1. let
  2. a = "1"
  3. b = "A"
  4. c = "\0\255"
  5. doAssert a.toHex() == "31"
  6. doAssert b.toHex() == "41"
  7. doAssert c.toHex() == "00FF"

Source Edit

  1. func toHex[T: SomeInteger](x: T): string

Shortcut for toHex(x, T.sizeof * 2)

Example:

  1. doAssert toHex(1984'i64) == "00000000000007C0"
  2. doAssert toHex(1984'i16) == "07C0"

Source Edit

  1. func toHex[T: SomeInteger](x: T; len: Positive): string

Converts x to its hexadecimal representation.

The resulting string will be exactly len characters long. No prefix like 0x is generated. x is treated as an unsigned value.

Example:

  1. let
  2. a = 62'u64
  3. b = 4097'u64
  4. doAssert a.toHex(3) == "03E"
  5. doAssert b.toHex(3) == "001"
  6. doAssert b.toHex(4) == "1001"
  7. doAssert toHex(62, 3) == "03E"
  8. doAssert toHex(-8, 6) == "FFFFF8"

Source Edit

  1. func toLowerAscii(c: char): char {....gcsafe, extern: "nsuToLowerAsciiChar",
  2. raises: [], tags: [], forbids: [].}

Returns the lower case version of character c.

This works only for the letters A-Z. See unicode.toLower for a version that works for any Unicode character.

See also:

Example:

  1. doAssert toLowerAscii('A') == 'a'
  2. doAssert toLowerAscii('e') == 'e'

Source Edit

  1. func toLowerAscii(s: string): string {....gcsafe, extern: "nsuToLowerAsciiStr",
  2. raises: [], tags: [], forbids: [].}

Converts string s into lower case.

This works only for the letters A-Z. See unicode.toLower for a version that works for any Unicode character.

See also:

Example:

  1. doAssert toLowerAscii("FooBar!") == "foobar!"

Source Edit

  1. func toOct(x: BiggestInt; len: Positive): string {....gcsafe, extern: "nsuToOct",
  2. raises: [], tags: [], forbids: [].}

Converts x into its octal representation.

The resulting string is always len characters long. No leading 0o prefix is generated.

Do not confuse it with toOctal func.

Example:

  1. let
  2. a = 62
  3. b = 513
  4. doAssert a.toOct(3) == "076"
  5. doAssert b.toOct(3) == "001"
  6. doAssert b.toOct(5) == "01001"

Source Edit

  1. func toOctal(c: char): string {....gcsafe, extern: "nsuToOctal", raises: [],
  2. tags: [], forbids: [].}

Converts a character c to its octal representation.

The resulting string may not have a leading zero. Its length is always exactly 3.

Do not confuse it with toOct func.

Example:

  1. doAssert toOctal('1') == "061"
  2. doAssert toOctal('A') == "101"
  3. doAssert toOctal('a') == "141"
  4. doAssert toOctal('!') == "041"

Source Edit

  1. func toUpperAscii(c: char): char {....gcsafe, extern: "nsuToUpperAsciiChar",
  2. raises: [], tags: [], forbids: [].}

Converts character c into upper case.

This works only for the letters A-Z. See unicode.toUpper for a version that works for any Unicode character.

See also:

Example:

  1. doAssert toUpperAscii('a') == 'A'
  2. doAssert toUpperAscii('E') == 'E'

Source Edit

  1. func toUpperAscii(s: string): string {....gcsafe, extern: "nsuToUpperAsciiStr",
  2. raises: [], tags: [], forbids: [].}

Converts string s into upper case.

This works only for the letters A-Z. See unicode.toUpper for a version that works for any Unicode character.

See also:

Example:

  1. doAssert toUpperAscii("FooBar!") == "FOOBAR!"

Source Edit

  1. func trimZeros(x: var string; decimalSep = '.') {....raises: [], tags: [],
  2. forbids: [].}

Trim trailing zeros from a formatted floating point value x (must be declared as var).

This modifies x itself, it does not return a copy.

Example:

  1. var x = "123.456000000"
  2. x.trimZeros()
  3. doAssert x == "123.456"

Source Edit

  1. func unescape(s: string; prefix = "\""; suffix = "\""): string {....gcsafe,
  2. extern: "nsuUnescape", raises: [ValueError], tags: [], forbids: [].}

Unescapes a string s.

This complements escape func as it performs the opposite operations.

If s does not begin with prefix and end with suffix a ValueError exception will be raised.

Source Edit

  1. func unindent(s: string; count: Natural = int.high; padding: string = " "): string {.
  2. ...gcsafe, extern: "nsuUnindent", raises: [], tags: [], forbids: [].}

Unindents each line in s by count amount of padding.

Note: This does not preserve the new line characters used in s.

See also:

Example:

  1. let x = """
  2. Hello
  3. There
  4. """.unindent()
  5. doAssert x == "Hello\nThere\n"

Source Edit

  1. func validIdentifier(s: string): bool {....gcsafe, extern: "nsuValidIdentifier",
  2. raises: [], tags: [], forbids: [].}

Returns true if s is a valid identifier.

A valid identifier starts with a character of the set IdentStartChars and is followed by any number of characters of the set IdentChars.

Example:

  1. doAssert "abc_def08".validIdentifier

Source Edit

Iterators

  1. iterator rsplit(s: string; sep: char; maxsplit: int = -1): string {....raises: [],
  2. tags: [], forbids: [].}

Splits the string s into substrings from the right using a string separator. Works exactly the same as split iterator except in reverse order.

  1. for piece in "foo:bar".rsplit(':'):
  2. echo piece

Results in:

  1. "bar"
  2. "foo"

Substrings are separated from the right by the char sep.

See also:

Source Edit

  1. iterator rsplit(s: string; sep: string; maxsplit: int = -1;
  2. keepSeparators: bool = false): string {....raises: [], tags: [],
  3. forbids: [].}

Splits the string s into substrings from the right using a string separator. Works exactly the same as split iterator except in reverse order.

  1. for piece in "foothebar".rsplit("the"):
  2. echo piece

Results in:

  1. "bar"
  2. "foo"

Substrings are separated from the right by the string sep

Note: Empty separator string results in returning an original string, following the interpretation “split by no element”.

See also:

Source Edit

  1. iterator rsplit(s: string; seps: set[char] = Whitespace; maxsplit: int = -1): string {.
  2. ...raises: [], tags: [], forbids: [].}

Splits the string s into substrings from the right using a string separator. Works exactly the same as split iterator except in reverse order.

  1. for piece in "foo bar".rsplit(WhiteSpace):
  2. echo piece

Results in:

  1. "bar"
  2. "foo"

Substrings are separated from the right by the set of chars seps

Note: Empty separator set results in returning an original string, following the interpretation “split by no element”.

See also:

Source Edit

  1. iterator split(s: string; sep: char; maxsplit: int = -1): string {....raises: [],
  2. tags: [], forbids: [].}

Splits the string s into substrings using a single separator.

Substrings are separated by the character sep. The code:

  1. for word in split(";;this;is;an;;example;;;", ';'):
  2. writeLine(stdout, word)

Results in:

  1. ""
  2. ""
  3. "this"
  4. "is"
  5. "an"
  6. ""
  7. "example"
  8. ""
  9. ""
  10. ""

See also:

Source Edit

  1. iterator split(s: string; sep: string; maxsplit: int = -1): string {....raises: [],
  2. tags: [], forbids: [].}

Splits the string s into substrings using a string separator.

Substrings are separated by the string sep. The code:

  1. for word in split("thisDATAisDATAcorrupted", "DATA"):
  2. writeLine(stdout, word)

Results in:

  1. "this"
  2. "is"
  3. "corrupted"

Note: Empty separator string results in returning an original string, following the interpretation “split by no element”.

See also:

Source Edit

  1. iterator split(s: string; seps: set[char] = Whitespace; maxsplit: int = -1): string {.
  2. ...raises: [], tags: [], forbids: [].}

Splits the string s into substrings using a group of separators.

Substrings are separated by a substring containing only seps.

  1. for word in split("this\lis an\texample"):
  2. writeLine(stdout, word)

…generates this output:

  1. "this"
  2. "is"
  3. "an"
  4. "example"

And the following code:

  1. for word in split("this:is;an$example", {';', ':', '$'}):
  2. writeLine(stdout, word)

…produces the same output as the first example. The code:

  1. let date = "2012-11-20T22:08:08.398990"
  2. let separators = {' ', '-', ':', 'T'}
  3. for number in split(date, separators):
  4. writeLine(stdout, number)

…results in:

  1. "2012"
  2. "11"
  3. "20"
  4. "22"
  5. "08"
  6. "08.398990"

Note: Empty separator set results in returning an original string, following the interpretation “split by no element”.

See also:

Source Edit

  1. iterator splitLines(s: string; keepEol = false): string {....raises: [], tags: [],
  2. forbids: [].}

Splits the string s into its containing lines.

Every character literal newline combination (CR, LF, CR-LF) is supported. The result strings contain no trailing end of line characters unless the parameter keepEol is set to true.

Example:

  1. for line in splitLines("\nthis\nis\nan\n\nexample\n"):
  2. writeLine(stdout, line)

Results in:

  1. ""
  2. "this"
  3. "is"
  4. "an"
  5. ""
  6. "example"
  7. ""

See also:

Source Edit

  1. iterator splitWhitespace(s: string; maxsplit: int = -1): string {....raises: [],
  2. tags: [], forbids: [].}

Splits the string s at whitespace stripping leading and trailing whitespace if necessary. If maxsplit is specified and is positive, no more than maxsplit splits is made.

The following code:

  1. let s = " foo \t bar baz "
  2. for ms in [-1, 1, 2, 3]:
  3. echo "------ maxsplit = ", ms, ":"
  4. for item in s.splitWhitespace(maxsplit=ms):
  5. echo '"', item, '"'

…results in:

  1. ------ maxsplit = -1:
  2. "foo"
  3. "bar"
  4. "baz"
  5. ------ maxsplit = 1:
  6. "foo"
  7. "bar baz "
  8. ------ maxsplit = 2:
  9. "foo"
  10. "bar"
  11. "baz "
  12. ------ maxsplit = 3:
  13. "foo"
  14. "bar"
  15. "baz"

See also:

Source Edit

  1. iterator tokenize(s: string; seps: set[char] = Whitespace): tuple[token: string,
  2. isSep: bool] {....raises: [], tags: [], forbids: [].}

Tokenizes the string s into substrings.

Substrings are separated by a substring containing only seps. Example:

  1. for word in tokenize(" this is an example "):
  2. writeLine(stdout, word)

Results in:

  1. (" ", true)
  2. ("this", false)
  3. (" ", true)
  4. ("is", false)
  5. (" ", true)
  6. ("an", false)
  7. (" ", true)
  8. ("example", false)
  9. (" ", true)

Source Edit

Exports

toLower, toLower, toLower, toUpper, toUpper, toUpper