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.
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:
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
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
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:
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:
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
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:
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:
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.
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.
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.
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:
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:
Examples:
string a = "Hölo World";
immutable(ubyte)[] b = a.representation;
string c = b.assumeUTF;

assert(a == c);