Menu

- Learn
- Documentation
  - Language Reference
  - Library Reference
  - Command-line Reference
  - Feature Overview
  - Articles
- Packages
- Community
  - Blog
  - Orgs using D
  - Twitter
  - Forums
  - IRC
  - Wiki
  - GitHub
  - Issues
  - Foundation
  - Donate
- Resources
  - Books
  - Tutorials
  - Tools
  - Editors
  - IDEs
  - Visual D
  - Acknowledgments
  - D Style
  - Glossary
  - Sitemap

Search
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

# std.string

String handling functions.

Category | Functions
--- | ---
Searching | column inPattern indexOf indexOfAny indexOfNeither lastIndexOf lastIndexOfAny lastIndexOfNeither
Comparison | countchars isNumeric
Mutation | capitalize munch removechars squeeze
Pruning and Filling | center chomp chompPrefix chop detabber detab entab entabber leftJustify outdent rightJustify strip stripLeft stripRight wrap
Substitution | abbrev soundex soundexer succ tr translate
Miscellaneous | assumeUTF fromStringz lineSplitter representation splitLines toStringz

Objects of types string, wstring, and dstring are value types and cannot be mutated element-by-element. For using mutation during building strings, use char[], wchar[], or dchar[]. The xxxstring types are preferable because they don't exhibit undesired aliasing, thus making code more robust.
The following functions are publicly imported:

Module | Functions
--- | ---
Publicly imported functions
std.algorithm | cmp count endsWith startsWith
std.array | join replace replaceInPlace split empty
std.format | format sformat
std.uni | icmp toLower toLowerInPlace toUpper toUpperInPlace

There is a rich set of functions for string handling defined in other modules. Functions related to Unicode and ASCII are found in std.uni and std.ascii, respectively. Other functions that have a wider generality than just strings can be found in std.algorithm and std.range.
See Also:

- std.algorithm and std.range for generic range algorithms
- std.ascii for functions that work with ASCII strings
- std.uni for functions that work with unicode strings

License:
Boost License 1.0.
Authors:
Walter Bright, Andrei Alexandrescu, Jonathan M Davis, and David L. 'SpottedTiger' Davis

Source: std/string.d

class `StringException`: object.Exception;
  Exception thrown on errors in std.string functions.
pure nothrow @nogc @system inout(char)[] `fromStringz`(inout(char)* `cString`);
  Parameters:

  inout(char)* `cString` | A `null`-terminated c-style string.

  Returns:
  A D-style array of char referencing the same string. The returned array will retain the same type qualifiers as the input.
  Important Note: The returned array is a slice of the original buffer. The original data is not changed and not copied.
  Examples:

      assert(fromStringz(null) == null);
      assert(fromStringz("foo") == "foo");

pure nothrow @trusted immutable(char)* `toStringz`(const(char)[] `s`);
pure nothrow @trusted immutable(char)* `toStringz`(in string `s`);
  Parameters:

  const(char)[] `s` | A D-style string.

  Returns:
  A C-style `null`-terminated string equivalent to `s`. `s` must not contain embedded '\0''`s` as any C function will treat the first '\0' that it sees as the end of the string. If `s`.empty is `true`, then a string containing only '\0' is returned.
  Important Note: When passing a char* to a C function, and the C function keeps it around for any reason, make sure that you keep a reference to it in your D code. Otherwise, it may become invalid during a garbage collection cycle and cause a nasty bug when the C code tries to use it.
  Examples:

      import core.stdc.string : strlen;
      import std.conv : to;

      auto p = toStringz("foo");
      assert(strlen(p) == 3);
      const(char)[] foo = "abbzxyzzy";
      p = toStringz(foo[3..5]);
      assert(strlen(p) == 2);

      string test = "";
      p = toStringz(test);
      assert(*p == 0);

      test = "\0";
      p = toStringz(test);
      assert(*p == 0);

      test = "foo\0";
      p = toStringz(test);
      assert(p[0] == 'f' && p[1] == 'o' && p[2] == 'o' && p[3] == 0);

      const string test2 = "";
      p = toStringz(test2);
      assert(*p == 0);

alias `CaseSensitive` = std.typecons.Flag!"caseSensitive".Flag;
  Flag indicating whether a search is case-sensitive.
ptrdiff_t `indexOf`(Range)(Range `s`, in dchar `c`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range);
ptrdiff_t `indexOf`(Range)(Range `s`, in dchar `c`, in size_t `startIdx`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range);
  Searches for character in range.
  Parameters:

  Range `s` | string or InputRange of characters to search in correct UTF format
  dchar `c` | character to search for
  size_t `startIdx` | starting index to a well-formed code point
  CaseSensitive `cs` | Yes.caseSensitive or No.caseSensitive

  Returns:
  the index of the first occurrence of `c` in `s` with respect to the start index `startIdx`. If `c` is not found, then -1 is returned. If `c` is found the value of the returned index is at least `startIdx`. If the parameters are not valid UTF, the result will still be in the range [-1 .. `s`.length], but will not be reliable otherwise.
  Throws:
  If the sequence starting at `startIdx` does not represent a well formed codepoint, then a std.utf.UTFException may be thrown.
  Examples:

      import std.typecons : No;

      string s = "Hello World";
      assert(indexOf(s, 'W') == 6);
      assert(indexOf(s, 'Z') == -1);
      assert(indexOf(s, 'w', No.caseSensitive) == 6);

  Examples:

      import std.typecons : No;

      string s = "Hello World";
      assert(indexOf(s, 'W', 4) == 6);
      assert(indexOf(s, 'Z', 100) == -1);
      assert(indexOf(s, 'w', 3, No.caseSensitive) == 6);

ptrdiff_t `indexOf`(Range, Char)(Range `s`, const(Char)[] `sub`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) && isSomeChar!Char);
@safe ptrdiff_t `indexOf`(Char1, Char2)(const(Char1)[] `s`, const(Char2)[] `sub`, in size_t `startIdx`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isSomeChar!Char1 && isSomeChar!Char2);
  Searches for substring in `s`.
  Parameters:

  Range `s` | string or ForwardRange of characters to search in correct UTF format
  const(Char)[] `sub` | substring to search for
  size_t `startIdx` | the index into `s` to start searching from
  CaseSensitive `cs` | Yes.caseSensitive or No.caseSensitive

  Returns:
  the index of the first occurrence of `sub` in `s` with respect to the start index `startIdx`. If `sub` is not found, then -1 is returned. If the arguments are not valid UTF, the result will still be in the range [-1 .. `s`.length], but will not be reliable otherwise. If `sub` is found the value of the returned index is at least `startIdx`.
  Throws:
  If the sequence starting at `startIdx` does not represent a well formed codepoint, then a std.utf.UTFException may be thrown.
  Bugs:
  Does not work with case insensitive strings where the mapping of tolower and toupper is not 1:1.
  Examples:

      import std.typecons : No;

      string s = "Hello World";
      assert(indexOf(s, "Wo", 4) == 6);
      assert(indexOf(s, "Zo", 100) == -1);
      assert(indexOf(s, "wo", 3, No.caseSensitive) == 6);

  Examples:

      import std.typecons : No;

      string s = "Hello World";
      assert(indexOf(s, "Wo") == 6);
      assert(indexOf(s, "Zo") == -1);
      assert(indexOf(s, "wO", No.caseSensitive) == 6);

pure @safe ptrdiff_t `lastIndexOf`(Char)(const(Char)[] `s`, in dchar `c`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isSomeChar!Char);
pure @safe ptrdiff_t `lastIndexOf`(Char)(const(Char)[] `s`, in dchar `c`, in size_t `startIdx`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isSomeChar!Char);
  Parameters:

  const(Char)[] `s` | string to search
  dchar `c` | character to search for
  size_t `startIdx` | the index into `s` to start searching from
  CaseSensitive `cs` | Yes.caseSensitive or No.caseSensitive

  Returns:
  The index of the last occurrence of `c` in `s`. If `c` is not found, then -1 is returned. The `startIdx` slices `s` in the following way `s`[0 .. `startIdx`]. `startIdx` represents a codeunit index in `s`.
  Throws:
  If the sequence ending at `startIdx` does not represent a well formed codepoint, then a std.utf.UTFException may be thrown.
  `cs` indicates whether the comparisons are case sensitive.
  Examples:

      import std.typecons : No;

      string s = "Hello World";
      assert(lastIndexOf(s, 'l') == 9);
      assert(lastIndexOf(s, 'Z') == -1);
      assert(lastIndexOf(s, 'L', No.caseSensitive) == 9);

  Examples:

      import std.typecons : No;

      string s = "Hello World";
      assert(lastIndexOf(s, 'l', 4) == 3);
      assert(lastIndexOf(s, 'Z', 1337) == -1);
      assert(lastIndexOf(s, 'L', 7, No.caseSensitive) == 3);

pure @safe ptrdiff_t `lastIndexOf`(Char1, Char2)(const(Char1)[] `s`, const(Char2)[] `sub`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isSomeChar!Char1 && isSomeChar!Char2);
pure @safe ptrdiff_t `lastIndexOf`(Char1, Char2)(const(Char1)[] `s`, const(Char2)[] `sub`, in size_t `startIdx`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isSomeChar!Char1 && isSomeChar!Char2);
  Parameters:

  const(Char1)[] `s` | string to search
  const(Char2)[] `sub` | substring to search for
  size_t `startIdx` | the index into `s` to start searching from
  CaseSensitive `cs` | Yes.caseSensitive or No.caseSensitive

  Returns:
  the index of the last occurrence of `sub` in `s`. If `sub` is not found, then -1 is returned. The `startIdx` slices `s` in the following way `s`[0 .. `startIdx`]. `startIdx` represents a codeunit index in `s`.
  Throws:
  If the sequence ending at `startIdx` does not represent a well formed codepoint, then a std.utf.UTFException may be thrown.
  `cs` indicates whether the comparisons are case sensitive.
  Examples:

      import std.typecons : No;

      string s = "Hello World";
      assert(lastIndexOf(s, "ll") == 2);
      assert(lastIndexOf(s, "Zo") == -1);
      assert(lastIndexOf(s, "lL", No.caseSensitive) == 2);

  Examples:

      import std.typecons : No;

      string s = "Hello World";
      assert(lastIndexOf(s, "ll", 4) == 2);
      assert(lastIndexOf(s, "Zo", 128) == -1);
      assert(lastIndexOf(s, "lL", 3, No.caseSensitive) == -1);

pure @safe ptrdiff_t `indexOfAny`(Char, Char2)(const(Char)[] `haystack`, const(Char2)[] `needles`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isSomeChar!Char && isSomeChar!Char2);
pure @safe ptrdiff_t `indexOfAny`(Char, Char2)(const(Char)[] `haystack`, const(Char2)[] `needles`, in size_t `startIdx`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isSomeChar!Char && isSomeChar!Char2);
  Returns the index of the first occurence of any of the elements in `needles` in `haystack`. If no element of `needles` is found, then -1 is returned. The `startIdx` slices `haystack` in the following way `haystack`[`startIdx` .. $]. `startIdx` represents a codeunit index in `haystack`. If the sequence ending at `startIdx` does not represent a well formed codepoint, then a std.utf.UTFException may be thrown.
  Parameters:

  const(Char)[] `haystack` | String to search for `needles` in.
  const(Char2)[] `needles` | Strings to search for in `haystack`.
  size_t `startIdx` | slices `haystack` like this `haystack`[`startIdx` .. $]. If the `startIdx` is greater equal the length of `haystack` the functions returns -1.
  CaseSensitive `cs` | Indicates whether the comparisons are case sensitive.

  Examples:

      import std.conv : to;

      ptrdiff_t i = "helloWorld".indexOfAny("Wr");
      assert(i == 5);
      i = "öällo world".indexOfAny("lo ");
      assert(i == 4, to!string(i));

  Examples:

      import std.conv : to;

      ptrdiff_t i = "helloWorld".indexOfAny("Wr", 4);
      assert(i == 5);

      i = "Foo öällo world".indexOfAny("lh", 3);
      assert(i == 8, to!string(i));

pure @safe ptrdiff_t `lastIndexOfAny`(Char, Char2)(const(Char)[] `haystack`, const(Char2)[] `needles`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isSomeChar!Char && isSomeChar!Char2);
pure @safe ptrdiff_t `lastIndexOfAny`(Char, Char2)(const(Char)[] `haystack`, const(Char2)[] `needles`, in size_t `stopIdx`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isSomeChar!Char && isSomeChar!Char2);
  Returns the index of the last occurence of any of the elements in `needles` in `haystack`. If no element of `needles` is found, then -1 is returned. The `stopIdx` slices `haystack` in the following way s[0 .. `stopIdx`]. `stopIdx` represents a codeunit index in `haystack`. If the sequence ending at startIdx does not represent a well formed codepoint, then a std.utf.UTFException may be thrown.
  Parameters:

  const(Char)[] `haystack` | String to search for `needles` in.
  const(Char2)[] `needles` | Strings to search for in `haystack`.
  size_t `stopIdx` | slices `haystack` like this `haystack`[0 .. `stopIdx`]. If the `stopIdx` is greater equal the length of `haystack` the functions returns -1.
  CaseSensitive `cs` | Indicates whether the comparisons are case sensitive.

  Examples:

      ptrdiff_t i = "helloWorld".lastIndexOfAny("Wlo");
      assert(i == 8);

      i = "Foo öäöllo world".lastIndexOfAny("öF");
      assert(i == 8);

  Examples:

      import std.conv : to;

      ptrdiff_t i = "helloWorld".lastIndexOfAny("Wlo", 4);
      assert(i == 3);

      i = "Foo öäöllo world".lastIndexOfAny("öF", 3);
      assert(i == 0);

pure @safe ptrdiff_t `indexOfNeither`(Char, Char2)(const(Char)[] `haystack`, const(Char2)[] `needles`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isSomeChar!Char && isSomeChar!Char2);
pure @safe ptrdiff_t `indexOfNeither`(Char, Char2)(const(Char)[] `haystack`, const(Char2)[] `needles`, in size_t `startIdx`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isSomeChar!Char && isSomeChar!Char2);
  Returns the index of the first occurence of any character not an elements in `needles` in `haystack`. If all element of `haystack` are element of `needles` -1 is returned.
  Parameters:

  const(Char)[] `haystack` | String to search for `needles` in.
  const(Char2)[] `needles` | Strings to search for in `haystack`.
  size_t `startIdx` | slices `haystack` like this `haystack`[`startIdx` .. $]. If the `startIdx` is greater equal the length of `haystack` the functions returns -1.
  CaseSensitive `cs` | Indicates whether the comparisons are case sensitive.

  Examples:

      assert(indexOfNeither("abba", "a", 2) == 2);
      assert(indexOfNeither("def", "de", 1) == 2);
      assert(indexOfNeither("dfefffg", "dfe", 4) == 6);

  Examples:

      assert(indexOfNeither("def", "a") == 0);
      assert(indexOfNeither("def", "de") == 2);
      assert(indexOfNeither("dfefffg", "dfe") == 6);

pure @safe ptrdiff_t `lastIndexOfNeither`(Char, Char2)(const(Char)[] `haystack`, const(Char2)[] `needles`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isSomeChar!Char && isSomeChar!Char2);
pure @safe ptrdiff_t `lastIndexOfNeither`(Char, Char2)(const(Char)[] `haystack`, const(Char2)[] `needles`, in size_t `stopIdx`, in CaseSensitive `cs` = Yes.caseSensitive)
if (isSomeChar!Char && isSomeChar!Char2);
  Returns the last index of the first occurence of any character that is not an elements in `needles` in `haystack`. If all element of `haystack` are element of `needles` -1 is returned.
  Parameters:

  const(Char)[] `haystack` | String to search for `needles` in.
  const(Char2)[] `needles` | Strings to search for in `haystack`.
  size_t `stopIdx` | slices `haystack` like this `haystack`[0 .. `stopIdx`] If the `stopIdx` is greater equal the length of `haystack` the functions returns -1.
  CaseSensitive `cs` | Indicates whether the comparisons are case sensitive.

  Examples:

      assert(lastIndexOfNeither("abba", "a") == 2);
      assert(lastIndexOfNeither("def", "f") == 1);

  Examples:

      assert(lastIndexOfNeither("def", "rsa", 3) == -1);
      assert(lastIndexOfNeither("abba", "a", 2) == 1);

pure nothrow @nogc @safe auto `representation`(Char)(Char[] `s`)
if (isSomeChar!Char);
  Returns the representation of a string, which has the same type as the string except the character type is replaced by ubyte, ushort, or uint depending on the character width.
  Parameters:

  Char[] `s` | The string to return the representation of.

  Returns:
  The representation of the passed string.
  Examples:

      string s = "hello";
      static assert(is(typeof(representation(s)) == immutable(ubyte)[]));
      assert(representation(s) is cast(immutable(ubyte)[]) s);
      assert(representation(s) == [0x68, 0x65, 0x6c, 0x6c, 0x6f]);

pure @trusted S `capitalize`(S)(S `input`)
if (isSomeString!S);
  Capitalize the first character of s and convert the rest of s to lowercase.
  Parameters:

  S `input` | The string to capitalize.

  Returns:
  The capitalized string.
  See Also:
  std.uni.asCapitalized for a lazy range version that doesn't allocate memory
  Examples:

      assert(capitalize("hello") == "Hello");
      assert(capitalize("World") == "World");

alias `KeepTerminator` = std.typecons.Flag!"keepTerminator".Flag;
pure @safe S[] `splitLines`(S)(S `s`, in KeepTerminator `keepTerm` = No.keepTerminator)
if (isSomeString!S);
  Split `s` into an array of lines according to the unicode standard using '\r', '\n', "\r\n", std.uni.lineSep, std.uni.paraSep, U+0085 (NEL), '\v' and '\f' as delimiters. If `keepTerm` is set to `KeepTerminator`.yes, then the delimiter is included in the strings returned.
  Does not throw on invalid UTF; such is simply passed unchanged to the output.
  Allocates memory; use lineSplitter for an alternative that does not.
  Adheres to Unicode 7.0.
  Parameters:

  S `s` | a string of chars, wchars, or dchars, or any custom type that casts to a string type
  `KeepTerminator` `keepTerm` | whether delimiter is included or not in the results

  Returns:
  array of strings, each element is a line that is a slice of `s`
  See Also:
  lineSplitter std.algorithm.splitter std.regex.splitter
  Examples:

      string s = "Hello\nmy\rname\nis";
      assert(splitLines(s) == ["Hello", "my", "name", "is"]);

auto `lineSplitter`(KeepTerminator keepTerm = No.keepTerminator, Range)(Range `r`)
if ((hasSlicing!Range && hasLength!Range && isSomeChar!(ElementType!Range) || isSomeString!Range) && !isConvertibleToString!Range);
  Split an array or slicable range of characters into a range of lines using '\`r`', '\n', '\v', '\f', "\`r`\n", std.uni.lineSep, std.uni.paraSep and '\u0085' (NEL) as delimiters. If keepTerm is set to Yes.keepTerminator, then the delimiter is included in the slices returned.
  Does not throw on invalid UTF; such is simply passed unchanged to the output.
  Adheres to Unicode 7.0.
  Does not allocate memory.
  Parameters:

  Range `r` | array of chars, wchars, or dchars or a slicable range
  keepTerm | whether delimiter is included or not in the results

  Returns:
  range of slices of the input range `r`
  See Also:
  splitLines std.algorithm.splitter std.regex.splitter
  Examples:

      import std.array : array;

      string s = "Hello\nmy\rname\nis";

      /* notice the call to $(D array) to turn the lazy range created by
      lineSplitter comparable to the $(D string[]) created by splitLines.
      */
      assert(lineSplitter(s).array == splitLines(s));

auto `stripLeft`(Range)(Range `input`)
if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range);
  Strips leading whitespace (as defined by std.uni.isWhite).
  Parameters:

  Range `input` | string or ForwardRange of characters

  Returns:
  `input` stripped of leading whitespace.

  Postconditions: `input` and the returned value will share the same tail (see std.array.sameTail).

  See Also:
  Generic stripping on ranges: std.algorithm.mutation.stripLeft
  Examples:

      import std.uni : lineSep, paraSep;
      assert(stripLeft("     hello world     ") ==
             "hello world     ");
      assert(stripLeft("\n\t\v\rhello world\n\t\v\r") ==
             "hello world\n\t\v\r");
      assert(stripLeft("hello world") ==
             "hello world");
      assert(stripLeft([lineSep] ~ "hello world" ~ lineSep) ==
             "hello world" ~ [lineSep]);
      assert(stripLeft([paraSep] ~ "hello world" ~ paraSep) ==
             "hello world" ~ [paraSep]);

      import std.array : array;
      import std.utf : byChar;
      assert(stripLeft("     hello world     "w.byChar).array ==
             "hello world     ");

auto `stripRight`(Range)(Range `str`)
if (isSomeString!Range || isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && !isConvertibleToString!Range && isSomeChar!(ElementEncodingType!Range));
  Strips trailing whitespace (as defined by std.uni.isWhite).
  Parameters:

  Range `str` | string or random access range of characters

  Returns:
  slice of `str` stripped of trailing whitespace.
  See Also:
  Generic stripping on ranges: std.algorithm.mutation.stripRight
  Examples:

      import std.uni : lineSep, paraSep;
      assert(stripRight("     hello world     ") ==
             "     hello world");
      assert(stripRight("\n\t\v\rhello world\n\t\v\r") ==
             "\n\t\v\rhello world");
      assert(stripRight("hello world") ==
             "hello world");
      assert(stripRight([lineSep] ~ "hello world" ~ lineSep) ==
             [lineSep] ~ "hello world");
      assert(stripRight([paraSep] ~ "hello world" ~ paraSep) ==
             [paraSep] ~ "hello world");

auto `strip`(Range)(Range `str`)
if (isSomeString!Range || isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && !isConvertibleToString!Range && isSomeChar!(ElementEncodingType!Range));
  Strips both leading and trailing whitespace (as defined by std.uni.isWhite).
  Parameters:

  Range `str` | string or random access range of characters

  Returns:
  slice of `str` stripped of leading and trailing whitespace.
  See Also:
  Generic stripping on ranges: std.algorithm.mutation.strip
  Examples:

      import std.uni : lineSep, paraSep;
      assert(strip("     hello world     ") ==
             "hello world");
      assert(strip("\n\t\v\rhello world\n\t\v\r") ==
             "hello world");
      assert(strip("hello world") ==
             "hello world");
      assert(strip([lineSep] ~ "hello world" ~ [lineSep]) ==
             "hello world");
      assert(strip([paraSep] ~ "hello world" ~ [paraSep]) ==
             "hello world");

Range `chomp`(Range)(Range `str`)
if ((isRandomAccessRange!Range && isSomeChar!(ElementEncodingType!Range) || isNarrowString!Range) && !isConvertibleToString!Range);
Range `chomp`(Range, C2)(Range `str`, const(C2)[] `delimiter`)
if ((isBidirectionalRange!Range && isSomeChar!(ElementEncodingType!Range) || isNarrowString!Range) && !isConvertibleToString!Range && isSomeChar!C2);
  If `str` ends with `delimiter`, then `str` is returned without `delimiter` on its end. If it `str` does not end with `delimiter`, then it is returned unchanged.
  If no `delimiter` is given, then one trailing '\r', '\n', "\r\n", '\f', '\v', std.uni.lineSep, std.uni.paraSep, or std.uni.nelSep is removed from the end of `str`. If `str` does not end with any of those characters, then it is returned unchanged.
  Parameters:

  Range `str` | string or indexable range of characters
  const(C2)[] `delimiter` | string of characters to be sliced off end of `str`[]

  Returns:
  slice of `str`
  Examples:

      import std.uni : lineSep, paraSep, nelSep;
      import std.utf : decode;
      assert(chomp(" hello world  \n\r") == " hello world  \n");
      assert(chomp(" hello world  \r\n") == " hello world  ");
      assert(chomp(" hello world  \f") == " hello world  ");
      assert(chomp(" hello world  \v") == " hello world  ");
      assert(chomp(" hello world  \n\n") == " hello world  \n");
      assert(chomp(" hello world  \n\n ") == " hello world  \n\n ");
      assert(chomp(" hello world  \n\n" ~ [lineSep]) == " hello world  \n\n");
      assert(chomp(" hello world  \n\n" ~ [paraSep]) == " hello world  \n\n");
      assert(chomp(" hello world  \n\n" ~ [ nelSep]) == " hello world  \n\n");
      assert(chomp(" hello world") == " hello world");
      assert(chomp("") == "");

      assert(chomp(" hello world", "orld") == " hello w");
      assert(chomp(" hello world", " he") == " hello world");
      assert(chomp("", "hello") == "");

      // Don't decode pointlessly
      assert(chomp("hello\xFE", "\r") == "hello\xFE");

Range `chompPrefix`(Range, C2)(Range `str`, const(C2)[] `delimiter`)
if ((isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) || isNarrowString!Range) && !isConvertibleToString!Range && isSomeChar!C2);
  If `str` starts with `delimiter`, then the part of `str` following `delimiter` is returned. If `str` does not start with
  `delimiter`, then it is returned unchanged.
  Parameters:

  Range `str` | string or forward range of characters
  const(C2)[] `delimiter` | string of characters to be sliced off front of `str`[]

  Returns:
  slice of `str`
  Examples:

      assert(chompPrefix("hello world", "he") == "llo world");
      assert(chompPrefix("hello world", "hello w") == "orld");
      assert(chompPrefix("hello world", " world") == "hello world");
      assert(chompPrefix("", "hello") == "");

Range `chop`(Range)(Range `str`)
if ((isBidirectionalRange!Range && isSomeChar!(ElementEncodingType!Range) || isNarrowString!Range) && !isConvertibleToString!Range);
  Returns `str` without its last character, if there is one. If `str` ends with "\r\n", then both are removed. If `str` is empty, then then it is returned unchanged.
  Parameters:

  Range `str` | string (must be valid UTF)

  Returns:
  slice of `str`
  Examples:

      assert(chop("hello world") == "hello worl");
      assert(chop("hello world\n") == "hello world");
      assert(chop("hello world\r") == "hello world");
      assert(chop("hello world\n\r") == "hello world\n");
      assert(chop("hello world\r\n") == "hello world");
      assert(chop("Walter Bright") == "Walter Brigh");
      assert(chop("") == "");

S `leftJustify`(S)(S `s`, size_t `width`, dchar `fillChar` = ' ')
if (isSomeString!S);
  Left justify `s` in a field `width` characters wide. `fillChar` is the character that will be used to fill up the space in the field that `s` doesn't fill.
  Parameters:

  S `s` | string
  size_t `width` | minimum field `width`
  dchar `fillChar` | used to pad end up to `width` characters

  Returns:
  GC allocated string
  See Also:
  leftJustifier, which does not allocate
  Examples:

      assert(leftJustify("hello", 7, 'X') == "helloXX");
      assert(leftJustify("hello", 2, 'X') == "hello");
      assert(leftJustify("hello", 9, 'X') == "helloXXXX");

auto `leftJustifier`(Range)(Range `r`, size_t `width`, dchar `fillChar` = ' ')
if (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range);
  Left justify s in a field `width` characters wide. `fillChar` is the character that will be used to fill up the space in the field that s doesn't fill.
  Parameters:

  Range `r` | string or range of characters
  size_t `width` | minimum field `width`
  dchar `fillChar` | used to pad end up to `width` characters

  Returns:
  a lazy range of the left justified result
  See Also:
  rightJustifier
  Examples:

      import std.algorithm.comparison : equal;
      import std.utf : byChar;
      assert(leftJustifier("hello", 2).equal("hello".byChar));
      assert(leftJustifier("hello", 7).equal("hello  ".byChar));
      assert(leftJustifier("hello", 7, 'x').equal("helloxx".byChar));

S `rightJustify`(S)(S `s`, size_t `width`, dchar `fillChar` = ' ')
if (isSomeString!S);
  Right justify `s` in a field `width` characters wide. `fillChar` is the character that will be used to fill up the space in the field that `s` doesn't fill.
  Parameters:

  S `s` | string
  size_t `width` | minimum field `width`
  dchar `fillChar` | used to pad end up to `width` characters

  Returns:
  GC allocated string
  See Also:
  rightJustifier, which does not allocate
  Examples:

      assert(rightJustify("hello", 7, 'X') == "XXhello");
      assert(rightJustify("hello", 2, 'X') == "hello");
      assert(rightJustify("hello", 9, 'X') == "XXXXhello");

auto `rightJustifier`(Range)(Range `r`, size_t `width`, dchar `fillChar` = ' ')
if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range);
  Right justify s in a field `width` characters wide. `fillChar` is the character that will be used to fill up the space in the field that s doesn't fill.
  Parameters:

  Range `r` | string or forward range of characters
  size_t `width` | minimum field `width`
  dchar `fillChar` | used to pad end up to `width` characters

  Returns:
  a lazy range of the right justified result
  See Also:
  leftJustifier
  Examples:

      import std.algorithm.comparison : equal;
      import std.utf : byChar;
      assert(rightJustifier("hello", 2).equal("hello".byChar));
      assert(rightJustifier("hello", 7).equal("  hello".byChar));
      assert(rightJustifier("hello", 7, 'x').equal("xxhello".byChar));

S `center`(S)(S `s`, size_t `width`, dchar `fillChar` = ' ')
if (isSomeString!S);
  Center `s` in a field `width` characters wide. `fillChar` is the character that will be used to fill up the space in the field that `s` doesn't fill.
  Parameters:

  S `s` | The string to `center`
  size_t `width` | Width of the field to `center` `s` in
  dchar `fillChar` | The character to use for filling excess space in the field

  Returns:
  The resulting center-justified string. The returned string is GC-allocated. To avoid GC allocation, use centerJustifier instead.
  Examples:

      assert(center("hello", 7, 'X') == "XhelloX");
      assert(center("hello", 2, 'X') == "hello");
      assert(center("hello", 9, 'X') == "XXhelloXX");

auto `centerJustifier`(Range)(Range `r`, size_t `width`, dchar `fillChar` = ' ')
if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range);
  Center justify `r` in a field `width` characters wide. `fillChar` is the character that will be used to fill up the space in the field that `r` doesn't fill.
  Parameters:

  Range `r` | string or forward range of characters
  size_t `width` | minimum field `width`
  dchar `fillChar` | used to pad end up to `width` characters

  Returns:
  a lazy range of the center justified result
  See Also:
  leftJustifier rightJustifier
  Examples:

      import std.algorithm.comparison : equal;
      import std.utf : byChar;
      assert(centerJustifier("hello", 2).equal("hello".byChar));
      assert(centerJustifier("hello", 8).equal(" hello  ".byChar));
      assert(centerJustifier("hello", 7, 'x').equal("xhellox".byChar));

pure auto `detab`(Range)(auto ref Range `s`, size_t `tabSize` = 8)
if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) || __traits(compiles, StringTypeOf!Range));
  Replace each tab character in `s` with the number of spaces necessary to align the following character at the next tab stop.
  Parameters:

  Range `s` | string
  size_t `tabSize` | distance between tab stops

  Returns:
  GC allocated string with tabs replaced with spaces
  Examples:

      assert(detab(" \n\tx", 9) == " \n         x");

auto `detabber`(Range)(Range `r`, size_t `tabSize` = 8)
if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range);
  Replace each tab character in `r` with the number of spaces necessary to align the following character at the next tab stop.
  Parameters:

  Range `r` | string or forward range
  size_t `tabSize` | distance between tab stops

  Returns:
  lazy forward range with tabs replaced with spaces
  Examples:

      import std.array : array;

      assert(detabber(" \n\tx", 9).array == " \n         x");

auto `entab`(Range)(Range `s`, size_t `tabSize` = 8)
if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range));
  Replaces spaces in `s` with the optimal number of tabs. All spaces and tabs at the end of a line are removed.
  Parameters:

  Range `s` | String to convert.
  size_t `tabSize` | Tab columns are `tabSize` spaces apart.

  Returns:
  GC allocated string with spaces replaced with tabs; use entabber to not allocate.
  See Also:
  entabber
  Examples:

      assert(entab("        x \n") == "\tx\n");

auto `entabber`(Range)(Range `r`, size_t `tabSize` = 8)
if (isForwardRange!Range && !isConvertibleToString!Range);
  Replaces spaces in range `r` with the optimal number of tabs. All spaces and tabs at the end of a line are removed.
  Parameters:

  Range `r` | string or forward range
  size_t `tabSize` | distance between tab stops

  Returns:
  lazy forward range with spaces replaced with tabs
  See Also:
  entab
  Examples:

      import std.array : array;
      assert(entabber("        x \n").array == "\tx\n");

pure @safe C1[] `translate`(C1, C2 = immutable(char))(C1[] `str`, in dchar[dchar] `transTable`, const(C2)[] `toRemove` = null)
if (isSomeChar!C1 && isSomeChar!C2);
pure @safe C1[] `translate`(C1, S, C2 = immutable(char))(C1[] `str`, in S[dchar] `transTable`, const(C2)[] `toRemove` = null)
if (isSomeChar!C1 && isSomeString!S && isSomeChar!C2);
  Replaces the characters in `str` which are keys in `transTable` with their corresponding values in `transTable`. `transTable` is an AA where its keys are dchar and its values are either dchar or some type of string. Also, if `toRemove` is given, the characters in it are removed from `str` prior to translation. `str` itself is unaltered. A copy with the changes is returned.
  See Also:
  tr std.array.replace
  Parameters:

  C1[] `str` | The original string.
  dchar[dchar] `transTable` | The AA indicating which characters to replace and what to replace them with.
  const(C2)[] `toRemove` | The characters to remove from the string.

  Examples:

      dchar[dchar] transTable1 = ['e' : '5', 'o' : '7', '5': 'q'];
      assert(translate("hello world", transTable1) == "h5ll7 w7rld");

      assert(translate("hello world", transTable1, "low") == "h5 rd");

      string[dchar] transTable2 = ['e' : "5", 'o' : "orange"];
      assert(translate("hello world", transTable2) == "h5llorange worangerld");

void `translate`(C1, C2 = immutable(char), Buffer)(C1[] `str`, in dchar[dchar] `transTable`, const(C2)[] `toRemove`, Buffer `buffer`)
if (isSomeChar!C1 && isSomeChar!C2 && isOutputRange!(Buffer, C1));
void `translate`(C1, S, C2 = immutable(char), Buffer)(C1[] `str`, in S[dchar] `transTable`, const(C2)[] `toRemove`, Buffer `buffer`)
if (isSomeChar!C1 && isSomeString!S && isSomeChar!C2 && isOutputRange!(Buffer, S));
  This is an overload of `translate` which takes an existing `buffer` to write the contents to.
  Parameters:

  C1[] `str` | The original string.
  dchar[dchar] `transTable` | The AA indicating which characters to replace and what to replace them with.
  const(C2)[] `toRemove` | The characters to remove from the string.
  Buffer `buffer` | An output range to write the contents to.

  Examples:

      import std.array : appender;
      dchar[dchar] transTable1 = ['e' : '5', 'o' : '7', '5': 'q'];
      auto buffer = appender!(dchar[])();
      translate("hello world", transTable1, null, buffer);
      assert(buffer.data == "h5ll7 w7rld");

      buffer.clear();
      translate("hello world", transTable1, "low", buffer);
      assert(buffer.data == "h5 rd");

      buffer.clear();
      string[dchar] transTable2 = ['e' : "5", 'o' : "orange"];
      translate("hello world", transTable2, null, buffer);
      assert(buffer.data == "h5llorange worangerld");

pure nothrow @trusted C[] `translate`(C = immutable(char))(in char[] `str`, in char[] `transTable`, in char[] `toRemove` = null)
if (is(Unqual!C == char));
  This is an ASCII-only overload of translate. It will not work with Unicode. It exists as an optimization for the cases where Unicode processing is not necessary.
  Unlike the other overloads of translate, this one does not take an AA. Rather, it takes a string generated by makeTransTable.
  The array generated by makeTransTable is 256 elements long such that the index is equal to the ASCII character being replaced and the value is equal to the character that it's being replaced with. Note that `translate` does not decode any of the characters, so you can actually pass it Extended ASCII characters if you want to (ASCII only actually uses 128 characters), but be warned that Extended ASCII characters are not valid Unicode and therefore will result in a UTFException being thrown from most other Phobos functions.
  Also, because no decoding occurs, it is possible to use this overload to `translate` ASCII characters within a proper UTF-8 string without altering the other, non-ASCII characters. It's replacing any code unit greater than 127 with another code unit or replacing any code unit with another code unit greater than 127 which will cause UTF validation issues.
  See Also:
  tr std.array.replace
  Parameters:

  char[] `str` | The original string.
  char[] `transTable` | The string indicating which characters to replace and what to replace them with. It is generated by makeTransTable.
  char[] `toRemove` | The characters to remove from the string.

pure nothrow @trusted string `makeTrans`(in char[] `from`, in char[] `to`);
  Do same thing as makeTransTable but allocate the translation table on the GC heap.
  Use makeTransTable instead.
  Examples:

      auto transTable1 = makeTrans("eo5", "57q");
      assert(translate("hello world", transTable1) == "h5ll7 w7rld");

      assert(translate("hello world", transTable1, "low") == "h5 rd");

pure nothrow @nogc @safe char[256] `makeTransTable`(in char[] `from`, in char[] `to`);
  Construct 256 character translation table, where characters in `from`[] are replaced by corresponding characters in `to`[].
  Parameters:

  char[] `from` | array of chars, less than or equal `to` 256 in length
  char[] `to` | corresponding array of chars `to` translate `to`

  Returns:
  translation array
pure @trusted void `translate`(C = immutable(char), Buffer)(in char[] `str`, in char[] `transTable`, in char[] `toRemove`, Buffer `buffer`)
if (is(Unqual!C == char) && isOutputRange!(Buffer, char));
  This is an ASCII-only overload of `translate` which takes an existing `buffer` to write the contents to.
  Parameters:

  char[] `str` | The original string.
  char[] `transTable` | The string indicating which characters to replace and what to replace them with. It is generated by makeTransTable.
  char[] `toRemove` | The characters to remove from the string.
  Buffer `buffer` | An output range to write the contents to.

  Examples:

      import std.array : appender;
      auto buffer = appender!(char[])();
      auto transTable1 = makeTransTable("eo5", "57q");
      translate("hello world", transTable1, null, buffer);
      assert(buffer.data == "h5ll7 w7rld");

      buffer.clear();
      translate("hello world", transTable1, "low", buffer);
      assert(buffer.data == "h5 rd");

pure @nogc @safe bool `inPattern`(S)(dchar `c`, in S `pattern`)
if (isSomeString!S);
  See if character `c` is in the `pattern`.

  Patterns: A `pattern` is an array of characters much like a character class in regular expressions. A sequence of characters can be given, such as "abcde". The '-' can represent a range of characters, as "a-e" represents the same `pattern` as "abcde". "a-fA-F0-9" represents all the hex characters. If the first character of a `pattern` is '^', then the `pattern` is negated, i.e. "^0-9" means any character except a digit. The functions `inPattern`, countchars, removeschars, and squeeze use patterns.

  Note: In the future, the `pattern` syntax may be improved to be more like regular expression character classes.

pure @nogc @safe bool `inPattern`(S)(dchar `c`, S[] `patterns`)
if (isSomeString!S);
  See if character `c` is in the intersection of the `patterns`.
pure @nogc @safe size_t `countchars`(S, S1)(S `s`, in S1 `pattern`)
if (isSomeString!S && isSomeString!S1);
  Count characters in `s` that match `pattern`.
pure @safe S `removechars`(S)(S `s`, in S `pattern`)
if (isSomeString!S);
  Return string that is `s` with all characters removed that match `pattern`.
S `squeeze`(S)(S `s`, in S `pattern` = null);
  Return string where sequences of a character in `s`[] from `pattern`[] are replaced with a single instance of that character. If `pattern` is `null`, it defaults to all characters.
pure @nogc @safe S1 `munch`(S1, S2)(ref S1 `s`, S2 `pattern`);
  Finds the position pos of the first character in `s` that does not match `pattern` (in the terminology used by std.string.inPattern). Updates `s` = `s`[pos..$]. Returns the slice from the beginning of the original (before update) string up to, and excluding, pos.
  The `munch` function is mostly convenient for skipping certain category of characters (e.g. whitespace) when parsing strings. (In such cases, the return value is not used.)
  Examples:

      string s = "123abc";
      string t = munch(s, "0123456789");
      assert(t == "123" && s == "abc");
      t = munch(s, "0123456789");
      assert(t == "" && s == "abc");

pure @safe S `succ`(S)(S `s`)
if (isSomeString!S);
  Return string that is the 'successor' to `s`[]. If the rightmost character is a-zA-Z0-9, it is incremented within its case or digits. If it generates a carry, the process is repeated with the one to its immediate left.
  Examples:

      assert(succ("1") == "2");
      assert(succ("9") == "10");
      assert(succ("999") == "1000");
      assert(succ("zz99") == "aaa00");

C1[] `tr`(C1, C2, C3, C4 = immutable(char))(C1[] `str`, const(C2)[] `from`, const(C3)[] `to`, const(C4)[] `modifiers` = null);
  Replaces the characters in `str` which are in `from` with the the corresponding characters in `to` and returns the resulting string.
  `tr` is based on Posix's `tr`, though it doesn't do everything that the Posix utility does.
  Parameters:

  C1[] `str` | The original string.
  const(C2)[] `from` | The characters `to` replace.
  const(C3)[] `to` | The characters `to` replace with.
  const(C4)[] `modifiers` | String containing `modifiers`.

  Modifiers:

  Modifier | Description
  'c' | Complement the list of characters in `from`
  'd' | Removes matching characters with no corresponding replacement in `to`
  's' | Removes adjacent duplicates in the replaced characters

  If the modifier 'd' is present, then the number of characters in `to` may be only 0 or 1.
  If the modifier 'd' is not present, and `to` is empty, then `to` is taken `to` be the same as `from`.
  If the modifier 'd' is not present, and `to` is shorter than `from`, then `to` is extended by replicating the last character in `to`.
  Both `from` and `to` may contain ranges using the '-' character (e.g. "a-d" is synonymous with "abcd".) Neither accept a leading '^' as meaning the complement of the string (use the 'c' modifier for that).
bool `isNumeric`(S)(S `s`, bool `bAllowSep` = false)
if (isSomeString!S || isRandomAccessRange!S && hasSlicing!S && isSomeChar!(ElementType!S) && !isInfinite!S);
  Takes a string `s` and determines if it represents a number. This function also takes an optional parameter, `bAllowSep`, which will accept the separator characters ',' and '_' within the string. But these characters should be stripped from the string before using any of the conversion functions like to!int(), to!float(), and etc else an error will occur.
  Also please note, that no spaces are allowed within the string anywhere whether it'`s` a leading, trailing, or embedded space(`s`), thus they too must be stripped from the string before using this function, or any of the conversion functions.
  Parameters:

  S `s` | the string or random access range to check
  bool `bAllowSep` | accept separator characters or not

  Returns:
  bool
  Examples:
  Integer Whole Number: (byte, ubyte, short, ushort, int, uint, long, and ulong) ['+'|'-']digit(`s`)[U|L|UL]

      assert(isNumeric("123"));
      assert(isNumeric("123UL"));
      assert(isNumeric("123L"));
      assert(isNumeric("+123U"));
      assert(isNumeric("-123L"));

  Examples:
  Floating-Point Number: (float, double, real, ifloat, idouble, and ireal) ['+'|'-']digit(`s`)[.][digit(`s`)][[e-|e+]digit(`s`)][i|f|L|Li|fi]] or [nan|nani|inf|-inf]

      assert(isNumeric("+123"));
      assert(isNumeric("-123.01"));
      assert(isNumeric("123.3e-10f"));
      assert(isNumeric("123.3e-10fi"));
      assert(isNumeric("123.3e-10L"));

      assert(isNumeric("nan"));
      assert(isNumeric("nani"));
      assert(isNumeric("-inf"));

  Examples:
  Floating-Point Number: (cfloat, cdouble, and creal) ['+'|'-']digit(`s`)[.][digit(`s`)][[e-|e+]digit(`s`)][+] [digit(`s`)[.][digit(`s`)][[e-|e+]digit(`s`)][i|f|L|Li|fi]] or [nan|nani|nan+nani|inf|-inf]

      assert(isNumeric("-123e-1+456.9e-10Li"));
      assert(isNumeric("+123e+10+456i"));
      assert(isNumeric("123+456"));

  Examples:
  `isNumeric` works with CTFE

      enum a = isNumeric("123.00E-5+1234.45E-12Li");
      enum b = isNumeric("12345xxxx890");

      static assert( a);
      static assert(!b);

char[4] `soundexer`(Range)(Range `str`)
if (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range);
  Soundex algorithm.
  The Soundex algorithm converts a word into 4 characters based on how the word sounds phonetically. The idea is that two spellings that sound alike will have the same Soundex value, which means that Soundex can be used for fuzzy matching of names.
  Parameters:

  Range `str` | String or InputRange to convert to Soundex representation.

  Returns:
  The four character array with the Soundex result in it. The array has zero's in it if there is no Soundex representation for the string.
  See Also:
  Wikipedia, The Soundex Indexing System soundex
  Bugs:
  Only works well with English names. There are other arguably better Soundex algorithms, but this one is the standard one.
pure nothrow @safe char[] `soundex`(const(char)[] `str`, char[] `buffer` = null);
  Like soundexer, but with different parameters and return value.
  Parameters:

  const(char)[] `str` | String to convert to Soundex representation.
  char[] `buffer` | Optional 4 char array to put the resulting Soundex characters into. If `null`, the return value `buffer` will be allocated on the heap.

  Returns:
  The four character array with the Soundex result in it. Returns `null` if there is no Soundex representation for the string.
  See Also:
  soundexer
pure @safe string[string] `abbrev`(string[] `values`);
  Construct an associative array consisting of all abbreviations that uniquely map to the strings in `values`.
  This is useful in cases where the user is expected to type in one of a known set of strings, and the program will helpfully autocomplete the string once sufficient characters have been entered that uniquely identify it.
  Examples:

      import std.string;

      static string[] list = [ "food", "foxy" ];
      auto abbrevs = abbrev(list);
      assert(abbrevs == ["fox": "foxy", "food": "food",
                         "foxy": "foxy", "foo": "food"]);

size_t `column`(Range)(Range `str`, in size_t `tabsize` = 8)
if ((isInputRange!Range && isSomeChar!(Unqual!(ElementEncodingType!Range)) || isNarrowString!Range) && !isConvertibleToString!Range);
  Compute column number at the end of the printed form of the string, assuming the string starts in the leftmost column, which is numbered starting from 0.
  Tab characters are expanded into enough spaces to bring the column number to the next multiple of `tabsize`. If there are multiple lines in the string, the column number of the last line is returned.
  Parameters:

  Range `str` | string or InputRange to be analyzed
  size_t `tabsize` | number of columns a tab character represents

  Returns:
  `column` number
  Examples:

      import std.utf : byChar, byWchar, byDchar;

      assert(column("1234 ") == 5);
      assert(column("1234 "w) == 5);
      assert(column("1234 "d) == 5);

      assert(column("1234 ".byChar()) == 5);
      assert(column("1234 "w.byWchar()) == 5);
      assert(column("1234 "d.byDchar()) == 5);

      // Tab stops are set at 8 spaces by default; tab characters insert enough
      // spaces to bring the column position to the next multiple of 8.
      assert(column("\t") == 8);
      assert(column("1\t") == 8);
      assert(column("\t1") == 9);
      assert(column("123\t") == 8);

      // Other tab widths are possible by specifying it explicitly:
      assert(column("\t", 4) == 4);
      assert(column("1\t", 4) == 4);
      assert(column("\t1", 4) == 5);
      assert(column("123\t", 4) == 4);

      // New lines reset the column number.
      assert(column("abc\n") == 0);
      assert(column("abc\n1") == 1);
      assert(column("abcdefg\r1234") == 4);
      assert(column("abc\u20281") == 1);
      assert(column("abc\u20291") == 1);
      assert(column("abc\u00851") == 1);
      assert(column("abc\u00861") == 5);

S `wrap`(S)(S `s`, in size_t `columns` = 80, S `firstindent` = null, S `indent` = null, in size_t `tabsize` = 8)
if (isSomeString!S);
  Wrap text into a paragraph.
  The input text string `s` is formed into a paragraph by breaking it up into a sequence of lines, delineated by \n, such that the number of `columns` is not exceeded on each line. The last line is terminated with a \n.
  Parameters:

  S `s` | text string to be wrapped
  size_t `columns` | maximum number of columns in the paragraph
  S `firstindent` | string used to indent first line of the paragraph
  S `indent` | string to use to indent following lines of the paragraph
  size_t `tabsize` | column spacing of tabs in `firstindent`[] and `indent`[]

  Returns:
  resulting paragraph as an allocated string
  Examples:

      assert(wrap("a short string", 7) == "a short\nstring\n");

      // wrap will not break inside of a word, but at the next space
      assert(wrap("a short string", 4) == "a\nshort\nstring\n");

      assert(wrap("a short string", 7, "\t") == "\ta\nshort\nstring\n");
      assert(wrap("a short string", 7, "\t", "    ") == "\ta\n    short\n    string\n");

pure @safe S `outdent`(S)(S `str`)
if (isSomeString!S);
  Removes one level of indentation from a multi-line string.
  This uniformly outdents the text as much as possible. Whitespace-only lines are always converted to blank lines.
  Does not allocate memory if it does not throw.
  Parameters:

  S `str` | multi-line string

  Returns:
  outdented string
  Throws:
  StringException if indentation is done with different sequences of whitespace characters.
  Examples:

      enum pretty = q{
         import std.stdio;
         void main() {
             writeln("Hello");
         }
      }.outdent();

      enum ugly = q{
      import std.stdio;
      void main() {
      writeln("Hello");
      }
      };

      assert(pretty == ugly);

pure @safe S[] `outdent`(S)(S[] `lines`)
if (isSomeString!S);
  Removes one level of indentation from an array of single-line strings.
  This uniformly outdents the text as much as possible. Whitespace-only `lines` are always converted to blank `lines`.
  Parameters:

  S[] `lines` | array of single-line strings

  Returns:
  `lines`[] is rewritten in place with outdented `lines`
  Throws:
  StringException if indentation is done with different sequences of whitespace characters.
pure auto `assumeUTF`(T)(T[] `arr`)
if (staticIndexOf!(Unqual!T, ubyte, ushort, uint) != -1);
  Assume the given array of integers `arr` is a well-formed UTF string and return it typed as a UTF string.
  ubyte becomes char, ushort becomes wchar and uint becomes dchar. Type qualifiers are preserved.
  Parameters:

  T[] `arr` | array of bytes, ubytes, shorts, ushorts, ints, or uints

  Returns:
  `arr` retyped as an array of chars, wchars, or dchars
  See Also:
  representation
  Examples:

      string a = "Hölo World";
      immutable(ubyte)[] b = a.representation;
      string c = b.assumeUTF;

      assert(a == c);

Copyright Digital Mars 2007-. | Page generated by Ddoc on Thu Feb 16 13:40:04 2017