class

String

Inherits Comparable / Reference / Object

A String represents an immutable sequence of UTF-8 characters.

A String is typically created with a string literal, enclosing UTF-8 characters in double quotes:

"hello world"

See String literals in the language reference.

A backslash can be used to denote some characters inside the string:

"\"" # double quote
"\\" # backslash
"\e" # escape
"\f" # form feed
"\n" # newline
"\r" # carriage return
"\t" # tab
"\v" # vertical tab

You can use a backslash followed by an u and four hexadecimal characters to denote a unicode codepoint written:

"\u0041" # == "A"

Or you can use curly braces and specify up to six hexadecimal numbers (0 to 10FFFF):

"\u{41}" # == "A"

A string can span multiple lines:

"hello
      world" # same as "hello\n      world"

Note that in the above example trailing and leading spaces, as well as newlines, end up in the resulting string. To avoid this, you can split a string into multiple lines by joining multiple literals with a backslash:

"hello " \
"world, " \
"no newlines" # same as "hello world, no newlines"

Alternatively, a backslash followed by a newline can be inserted inside the string literal:

"hello \
     world, \
     no newlines" # same as "hello world, no newlines"

In this case, leading whitespace is not included in the resulting string.

If you need to write a string that has many double quotes, parentheses, or similar characters, you can use alternative literals:

# Supports double quotes and nested parentheses
%(hello ("world")) # same as "hello (\"world\")"

# Supports double quotes and nested brackets
%[hello ["world"]] # same as "hello [\"world\"]"

# Supports double quotes and nested curlies
%{hello {"world"}} # same as "hello {\"world\"}"

# Supports double quotes and nested angles
%<hello <"world">> # same as "hello <\"world\">"

To create a String with embedded expressions, you can use string interpolation:

a = 1
b = 2
"sum = #{a + b}" # "sum = 3"

This ends up invoking Object#to_s(IO) on each expression enclosed by #{...}.

If you need to dynamically build a string, use String#build or IO::Memory.

Non UTF-8 valid strings

A string might end up being composed of bytes which form an invalid byte sequence according to UTF-8. This can happen if the string is created via one of the constructors that accept bytes, or when getting a string from String.build or IO::Memory. No exception will be raised, but every byte that doesn't start a valid UTF-8 byte sequence is interpreted as though it encodes the Unicode replacement character (U+FFFD) by itself. For example:

# here 255 is not a valid byte value in the UTF-8 encoding
string = String.new(Bytes[255, 97])
string.valid_encoding? # => false

# The first char here is the unicode replacement char
string.chars # => ['�', 'a']

One can also create strings with specific byte value in them by using octal and hexadecimal escape sequences:

# Octal escape sequences
"\101" # # => "A"
"\12"  # # => "\n"
"\1"   # string with one character with code point 1
"\377" # string with one byte with value 255

# Hexadecimal escape sequences
"\x41" # # => "A"
"\xFF" # string with one byte with value 255

The reason for allowing strings that don't have a valid UTF-8 sequence is that the world is full of content that isn't properly encoded, and having a program raise an exception or stop because of this is not good. It's better if programs are more resilient, but show a replacement character when there's an error in incoming data.

Note that this interpretation only applies to methods inside Crystal; calling #to_slice or #to_unsafe, e.g. when passing a string to a C library, will expose the invalid UTF-8 byte sequences. In particular, Regex's underlying engine may reject strings that are not valid UTF-8, or it may invoke undefined behavior on invalid strings. If this is undesired, #scrub could be used to remove the offending byte sequences first.

NOTE: This type cannot be inherited due to its special memory representation.

Constructors

additive_identity

Returns the empty string.

Source
build(capacity = 64, &) : self

Builds a String by creating a String::Builder with the given initial capacity, yielding it to the block and finally getting a String out of it. The String::Builder automatically resizes as needed.

str = String.build do |str|
  str << "hello "
  str << 1
end
str # => "hello 1"
Source
from_json_object_key?(key : String) : String
Source
from_utf16(slice : Slice(UInt16), *, truncate_at_null : Bool = false) : String

Decodes the given slice UTF-16 sequence into a String.

Invalid values are encoded using the unicode replacement char with codepoint 0xfffd.

If truncate_at_null is true, only the characters up to and not including the first null character are copied.

slice = Slice[104_u16, 105_u16, 32_u16, 55296_u16, 56485_u16]
String.from_utf16(slice) # => "hi 𐂥"

slice = UInt16.slice(102, 111, 111, 0, 98, 97, 114)
String.from_utf16(slice, truncate_at_null: true) # => "foo"
Source
interpolation(value : String, char : Char) : String

Implementation of string interpolation of a string and a char.

For example, this code will end up invoking this method:

char = '!'
"hello#{char}" # same as String.interpolation("hello", char)

In this case the implementation just does value + char.

NOTE: there should never be a need to call this method instead of using string interpolation.

Source
interpolation(char : Char, value : String) : String

Implementation of string interpolation of a char and a string.

For example, this code will end up invoking this method:

char = '!'
"#{char}hello" # same as String.interpolation(char, "hello")

In this case the implementation just does char + value.

NOTE: there should never be a need to call this method instead of using string interpolation.

Source
interpolation(value : String) : String

Implementation of string interpolation of a single string.

For example, this code will end up invoking this method:

value = "hello"
"#{value}" # same as String.interpolation(value)

In this case the implementation just returns the same string.

NOTE: there should never be a need to call this method instead of using string interpolation.

Source
interpolation(value) : String

Implementation of string interpolation of a single non-string value.

For example, this code will end up invoking this method:

value = 123
"#{value}" # same as String.interpolation(value)

In this case the implementation just returns the result of calling value.to_s.

NOTE: there should never be a need to call this method instead of using string interpolation.

Source
interpolation(*values : String) : String

Implementation of string interpolation of multiple string values.

For example, this code will end up invoking this method:

value1 = "hello"
value2 = "world"
"#{value1} #{value2}!" # same as String.interpolation(value1, " ", value2, "!")

In this case the implementation can pre-compute the needed string bytesize and so it's a bit more performant than interpolating non-string values.

NOTE: there should never be a need to call this method instead of using string interpolation.

Source
interpolation(*values : *T) : String forall T

Implementation of string interpolation of multiple, possibly non-string values.

For example, this code will end up invoking this method:

value1 = "hello"
value2 = 123
"#{value1} #{value2}!" # same as String.interpolation(value1, " ", value2, "!")

In this case the implementation will call String.build with the given values.

NOTE: there should never be a need to call this method instead of using string interpolation.

Source
new(bytes : Bytes, encoding : String, invalid : Symbol | Nil = nil) : String

Creates a new String from the given bytes, which are encoded in the given encoding.

The invalid argument can be:

  • nil: an exception is raised on invalid byte sequences
  • :skip: invalid byte sequences are ignored
slice = Slice.new(2, 0_u8)
slice[0] = 186_u8
slice[1] = 195_u8
String.new(slice, "GB2312") # => "好"
Source
new(chars : Pointer(UInt8), bytesize, size = 0)

Creates a new String from a pointer, indicating its bytesize count and, optionally, the UTF-8 codepoints count (size). Bytes will be copied from the pointer.

If the given size is zero, the amount of UTF-8 codepoints will be lazily computed when needed.

ptr = Pointer.malloc(4) { |i| ('a'.ord + i).to_u8 }
String.new(ptr, 2) # => "ab"
Source
new(chars : Pointer(UInt8))

Creates a String from a pointer. Bytes will be copied from the pointer.

This method is unsafe: the pointer must point to data that eventually contains a zero byte that indicates the ends of the string. Otherwise, the result of this method is undefined and might cause a segmentation fault.

This method is typically used in C bindings, where you get a char* from a library and the library guarantees that this pointer eventually has an ending zero byte.

ptr = Pointer.malloc(5) { |i| i == 4 ? 0_u8 : ('a'.ord + i).to_u8 }
String.new(ptr) # => "abcd"
Source
new(pull : JSON::PullParser) : self
Source
new(slice : Bytes, *, truncate_at_null : Bool = false)

Creates a String from the given slice. Bytes will be copied from the slice.

This method is always safe to call, and the resulting string will have the contents and size of the slice.

If truncate_at_null is true, only the characters up to and not including the first null character are copied.

slice = Slice.new(4) { |i| ('a'.ord + i).to_u8 }
String.new(slice) # => "abcd"

slice = UInt8.slice(102, 111, 111, 0, 98, 97, 114)
String.new(slice, truncate_at_null: true) # => "foo"
Source
new(capacity : Int, &)

Creates a new String by allocating a buffer (Pointer(UInt8)) with the given capacity, then yielding that buffer. The block must return a tuple with the bytesize and size (UTF-8 codepoints count) of the String. If the returned size is zero, the UTF-8 codepoints count will be lazily computed.

The bytesize returned by the block must be less than or equal to the capacity given to this String, otherwise ArgumentError is raised.

If you need to build a String where the maximum capacity is unknown, use String#build.

str = String.new(4) do |buffer|
  buffer[0] = 'a'.ord.to_u8
  buffer[1] = 'b'.ord.to_u8
  {2, 2}
end
str # => "ab"
Source

Class methods

from_utf16(pointer : Pointer(UInt16)) : Tuple(String, Pointer(UInt16))

Decodes the given slice UTF-16 sequence into a String and returns the pointer after reading. The string ends when a zero value is found.

slice = Slice[104_u16, 105_u16, 0_u16, 55296_u16, 56485_u16, 0_u16]
String.from_utf16(slice) # => "hi\0000𐂥\u0000"
pointer = slice.to_unsafe
string, pointer = String.from_utf16(pointer)
string # => "hi"
string, pointer = String.from_utf16(pointer)
string # => "𐂥"

Invalid values are encoded using the unicode replacement char with codepoint 0xfffd.

Source

Instance methods

%(other) : String

Interpolates other into the string using top-level ::sprintf.

"I have %d apples" % 5                                             # => "I have 5 apples"
"%s, %s, %s, D" % ['A', 'B', 'C']                                  # => "A, B, C, D"
"sum: %{one} + %{two} = %{three}" % {one: 1, two: 2, three: 1 + 2} # => "sum: 1 + 2 = 3"
"I have %<apples>s apples" % {apples: 4}                           # => "I have 4 apples"
Source
*(times : Int) : String

Makes a new String by adding str to itself times times.

"Developers! " * 4
# => "Developers! Developers! Developers! Developers! "
Source
+(other : self) : String

Concatenates str and other.

"abc" + "def" # => "abcdef"
"abc" + 'd'   # => "abcd"
Source
+(char : Char) : String

Concatenates str and other.

"abc" + "def" # => "abcdef"
"abc" + 'd'   # => "abcd"
Source
<=>(other : self) : Int32

The comparison operator.

Compares this string with other, returning -1, 0 or 1 depending on whether this string is less, equal or greater than other.

Comparison is done byte-per-byte: if a byte is less than the other corresponding byte, -1 is returned and so on. This means two strings containing invalid UTF-8 byte sequences may compare unequal, even when they both produce the Unicode replacement character at the same string indices.

If the strings are of different lengths, and the strings are equal when compared up to the shortest length, then the longer string is considered greater than the shorter one.

"abcdef" <=> "abcde"   # => 1
"abcdef" <=> "abcdef"  # => 0
"abcdef" <=> "abcdefg" # => -1
"abcdef" <=> "ABCDEF"  # => 1

The comparison is case-sensitive. #compare is a case-insensitive alternative.

Source
==(other : self) : Bool

Returns true if this string is equal to `other.

Equality is checked byte-per-byte: if any byte is different from the corresponding byte, it returns false. This means two strings containing invalid UTF-8 byte sequences may compare unequal, even when they both produce the Unicode replacement character at the same string indices.

Thus equality is case-sensitive, as it is with the comparison operator (#<=>). #compare offers a case-insensitive alternative.

"abcdef" == "abcde"   # => false
"abcdef" == "abcdef"  # => true
"abcdef" == "abcdefg" # => false
"abcdef" == "ABCDEF"  # => false

"abcdef".compare("ABCDEF", case_insensitive: true) == 0 # => true
Source
=~(regex : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Int32 | Nil

Tests whether str matches regex. If successful, it returns the position of the first match. If unsuccessful, it returns nil.

If the argument isn't a Regex, it returns nil.

"Haystack" =~ /ay/ # => 1
"Haystack" =~ /z/  # => nil

"Haystack" =~ 45 # => nil
Source
=~(other, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Nil

Tests whether str matches regex. If successful, it returns the position of the first match. If unsuccessful, it returns nil.

If the argument isn't a Regex, it returns nil.

"Haystack" =~ /ay/ # => 1
"Haystack" =~ /z/  # => nil

"Haystack" =~ 45 # => nil
Source
[](start : Int, count : Int) : String

Returns a substring starting from the start character of size count.

Negative start is added to self.size, thus it's treated as a character index counting from the end, -1 designating the last character.

Raises IndexError if start index is out of bounds. Raises ArgumentError if count is negative.

Source
[](regex : Regex, group, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : String
Source
[](index : Int) : Char

Returns the Char at the given index.

Negative indices can be used to start counting from the end of the string.

Raises IndexError if the index is out of bounds.

"hello"[0]  # => 'h'
"hello"[1]  # => 'e'
"hello"[-1] # => 'o'
"hello"[-2] # => 'l'
"hello"[5]  # raises IndexError
Source
[](range : Range) : String

Returns the substring indicated by range as span of character indices.

The substring ranges from self[range.begin] to self[range.end] (or self[range.end - 1] if the range is exclusive). It can be smaller than range.size if the end index is larger than self.size.

s = "abcde"
s[1..3] # => "bcd"
# range.end > s.size
s[3..7] # => "de"

Open ended ranges are clamped at the start and end of self, respectively.

# open ended ranges
s[2..] # => "cde"
s[..2] # => "abc"

Negative range values are added to self.size, thus they are treated as character indices counting from the end, -1 designating the last character.

# negative indices, both ranges are equivalent for `s`
s[1..3]   # => "bcd"
s[-4..-2] # => "bcd"
# Mixing negative and positive indices, both ranges are equivalent for `s`
s[1..-2] # => "bcd"
s[-4..3] # => "bcd"

Raises IndexError if the start index it out of range (range.begin > self.size || range.begin < -self.size). If range.begin == self.sizean empty string is returned. Ifrange.begin > range.end`, an empty string is returned.

# range.begin > array.size
s[6..10] # raise IndexError
# range.begin == s.size
s[5..10] # => ""
# range.begin > range.end
s[3..1]   # => ""
s[-2..-4] # => ""
s[-2..1]  # => ""
s[3..-4]  # => ""
Source
[](str : String | Char)

Returns str if str is found in this string.

"crystal"["cry"]  # => "cry"
"crystal"["ruby"] # raises NilAssertionError
Source
[](regex : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : String
Source
[]?(start : Int, count : Int) : String | Nil

Like #[](Int, Int) but returns nil if the start index is out of bounds.

Source
[]?(regex : Regex, group, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : String | Nil
Source
[]?(range : Range) : String | Nil

Like #[](Range), but returns nil if range.begin is out of range.

"hello"[6..7]? # => nil
"hello"[6..]?  # => nil
Source
[]?(index : Int) : Char | Nil

Returns the character at index or nil if it's out of range.

Negative indices can be used to start counting from the end of the string.

See #[] for a raising alternative.

"hello"[0]?  # => 'h'
"hello"[1]?  # => 'e'
"hello"[-1]? # => 'o'
"hello"[-2]? # => 'l'
"hello"[5]?  # => nil
Source
[]?(str : String | Char)

Returns str if str is found in this string, or nil otherwise.

"crystal"["cry"]?  # => "cry"
"crystal"["ruby"]? # => nil
Source
[]?(regex : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : String | Nil
Source
ascii_only?

Returns true if this String is comprised in its entirety by ASCII characters.

"hello".ascii_only? # => true
"你好".ascii_only?    # => false
Source
blank?

Returns true if this string consists exclusively of unicode whitespace.

"".blank?        # => true
"   ".blank?     # => true
"   a   ".blank? # => false
Source
byte_at(index) : UInt8

Returns the byte at the given index.

Raises IndexError if the index is out of bounds.

"¥hello".byte_at(0)  # => 194
"¥hello".byte_at(1)  # => 165
"¥hello".byte_at(2)  # => 104
"¥hello".byte_at(-1) # => 111
"¥hello".byte_at(6)  # => 111
"¥hello".byte_at(7)  # raises IndexError
Source
byte_at(index, &)

Returns the byte at the given index, or yields if out of bounds.

"¥hello".byte_at(6) { "OUT OF BOUNDS" } # => 111
"¥hello".byte_at(7) { "OUT OF BOUNDS" } # => "OUT OF BOUNDS"
Source
byte_at?(index) : UInt8 | Nil

Returns the byte at the given index, or nil if out of bounds.

"¥hello".byte_at?(0)  # => 194
"¥hello".byte_at?(1)  # => 165
"¥hello".byte_at?(2)  # => 104
"¥hello".byte_at?(-1) # => 111
"¥hello".byte_at?(6)  # => 111
"¥hello".byte_at?(7)  # => nil
Source
byte_index(byte : Int, offset : Int32 = 0) : Int32 | Nil

Returns the index of the first occurrence of byte in the string, or nil if not present. If offset is present, it defines the position to start the search.

Negative offset can be used to start the search from the end of the string.

"Hello, World".byte_index(0x6f)             # => 4
"Hello, World".byte_index(0x5a)             # => nil
"Hello, World".byte_index(0x6f, 5)          # => 8
"💣".byte_index(0xA3)                        # => 3
"Dizzy Miss Lizzy".byte_index('z'.ord)      # => 2
"Dizzy Miss Lizzy".byte_index('z'.ord, 3)   # => 3
"Dizzy Miss Lizzy".byte_index('z'.ord, -4)  # => 13
"Dizzy Miss Lizzy".byte_index('z'.ord, -17) # => nil
Source
byte_index(char : Char, offset = 0) : Int32 | Nil

Returns the index of the first occurrence of char in the string, or nil if not present. If offset is present, it defines the position to start the search.

Negative offset can be used to start the search from the end of the string.

"Hello, World".byte_index('o')          # => 4
"Hello, World".byte_index('Z')          # => nil
"Hello, World".byte_index('o', 5)       # => 8
"Hi, 💣".byte_index('💣')                 # => 4
"Dizzy Miss Lizzy".byte_index('z')      # => 2
"Dizzy Miss Lizzy".byte_index('z', 3)   # => 3
"Dizzy Miss Lizzy".byte_index('z', -4)  # => 13
"Dizzy Miss Lizzy".byte_index('z', -17) # => nil
Source
byte_index(search : String, offset = 0) : Int32 | Nil

Returns the byte index of search in the string, or nil if the string is not present. If offset is present, it defines the position to start the search.

Negative offset can be used to start the search from the end of the string.

"¥hello".byte_index("hello")              # => 2
"hello".byte_index("world")               # => nil
"Dizzy Miss Lizzy".byte_index("izzy")     # => 1
"Dizzy Miss Lizzy".byte_index("izzy", 2)  # => 12
"Dizzy Miss Lizzy".byte_index("izzy", -4) # => 12
"Dizzy Miss Lizzy".byte_index("izzy", -3) # => nil
Source
byte_index(pattern : Regex, offset = 0, options : Regex::MatchOptions = Regex::MatchOptions::None) : Int32 | Nil

Returns the byte index of the regex pattern in the string, or nil if the pattern does not find a match. If offset is present, it defines the position to start the search.

Negative offset can be used to start the search from the end of the string.

"hello world".byte_index(/o/)             # => 4
"hello world".byte_index(/o/, offset: 4)  # => 4
"hello world".byte_index(/o/, offset: 5)  # => 7
"hello world".byte_index(/o/, offset: -1) # => nil
"hello world".byte_index(/y/)             # => nil
Source
byte_index_to_char_index(index) : Int32 | Nil

Returns the char index of a byte index, or nil if out of bounds.

It is valid to pass #bytesize to index, and in this case the answer will be the size of this string.

Source
byte_slice(start : Int, count : Int) : String

Returns a new string built from count bytes starting at start byte.

start can be negative to start counting from the end of the string. If count is bigger than the number of bytes from start to #bytesize, only remaining bytes are returned.

This method should be avoided, unless the string is proven to be ASCII-only (for example #ascii_only?), or the byte positions are known to be at character boundaries. Otherwise, multi-byte characters may be split, leading to an invalid UTF-8 encoding.

Raises IndexError if the start index is out of bounds.

Raises ArgumentError if count is negative.

"hello".byte_slice(0, 2)   # => "he"
"hello".byte_slice(0, 100) # => "hello"
"hello".byte_slice(-2, 3)  # => "lo"
"hello".byte_slice(-2, 5)  # => "lo"
"¥hello".byte_slice(0, 2)  # => "¥"
"¥hello".byte_slice(2, 2)  # => "he"
"¥hello".byte_slice(0, 1)  # => "\xC2" (invalid UTF-8 character)
"¥hello".byte_slice(1, 1)  # => "\xA5" (invalid UTF-8 character)
"¥hello".byte_slice(1, 2)  # => "\xA5h" (invalid UTF-8 character)
"hello".byte_slice(6, 2)   # raises IndexError
"hello".byte_slice(-6, 2)  # raises IndexError
"hello".byte_slice(0, -2)  # raises ArgumentError
Source
byte_slice(range : Range) : String

Returns a new string built from byte in range.

Byte indices can be negative to start counting from the end of the string. If the end index is bigger than #bytesize, only remaining bytes are returned.

This method should be avoided, unless the string is proven to be ASCII-only (for example #ascii_only?), or the byte positions are known to be at character boundaries. Otherwise, multi-byte characters may be split, leading to an invalid UTF-8 encoding.

Raises IndexError if the range begin is out of bounds.

"hello".byte_slice(0..2)   # => "hel"
"hello".byte_slice(0..100) # => "hello"
"hello".byte_slice(-2..3)  # => "l"
"hello".byte_slice(-2..5)  # => "lo"
"¥hello".byte_slice(0...2) # => "¥"
"¥hello".byte_slice(2...4) # => "he"
"¥hello".byte_slice(0..0)  # => "\xC2" (invalid UTF-8 character)
"¥hello".byte_slice(1..1)  # => "\xA5" (invalid UTF-8 character)
"¥hello".byte_slice(1..2)  # => "\xA5h" (invalid UTF-8 character)
"hello".byte_slice(6..2)   # raises IndexError
"hello".byte_slice(-6..2)  # raises IndexError
Source
byte_slice(start : Int) : String

Returns a substring starting from the start byte.

start can be negative to start counting from the end of the string.

This method should be avoided, unless the string is proven to be ASCII-only (for example #ascii_only?), or the byte positions are known to be at character boundaries. Otherwise, multi-byte characters may be split, leading to an invalid UTF-8 encoding.

Raises IndexError if start index is out of bounds.

"hello".byte_slice(0)  # => "hello"
"hello".byte_slice(2)  # => "llo"
"hello".byte_slice(-2) # => "lo"
"¥hello".byte_slice(2) # => "hello"
"¥hello".byte_slice(1) # => "\xA5hello" (invalid UTF-8 character)
"hello".byte_slice(6)  # raises IndexError
"hello".byte_slice(-6) # raises IndexError
Source
byte_slice?(start : Int, count : Int) : String | Nil

Like byte_slice(Int, Int) but returns Nil if the start index is out of bounds.

Raises ArgumentError if count is negative.

"hello".byte_slice?(0, 2)   # => "he"
"hello".byte_slice?(0, 100) # => "hello"
"hello".byte_slice?(6, 2)   # => nil
"hello".byte_slice?(-6, 2)  # => nil
"hello".byte_slice?(0, -2)  # raises ArgumentError
Source
byte_slice?(range : Range) : String | Nil

Like byte_slice(Range) but returns Nil if range begin is out of bounds.

"hello".byte_slice?(0..2)   # => "hel"
"hello".byte_slice?(0..100) # => "hello"
"hello".byte_slice?(6..8)   # => nil
"hello".byte_slice?(-6..2)  # => nil
Source
byte_slice?(start : Int) : String | Nil

Returns a substring starting from the start byte.

start can be negative to start counting from the end of the string.

This method should be avoided, unless the string is proven to be ASCII-only (for example #ascii_only?), or the byte positions are known to be at character boundaries. Otherwise, multi-byte characters may be split, leading to an invalid UTF-8 encoding.

Returns nil if start index is out of bounds.

"hello".byte_slice?(0)  # => "hello"
"hello".byte_slice?(2)  # => "llo"
"hello".byte_slice?(-2) # => "lo"
"¥hello".byte_slice?(2) # => "hello"
"¥hello".byte_slice?(1) # => "\xA5hello" (invalid UTF-8 character)
"hello".byte_slice?(6)  # => nil
"hello".byte_slice?(-6) # => nil
Source
bytes

Returns this string's bytes as an Array(UInt8).

"hello".bytes # => [104, 101, 108, 108, 111]
"你好".bytes    # => [228, 189, 160, 229, 165, 189]
Source
bytesize

Returns the number of bytes in this string.

"hello".bytesize # => 5
"你好".bytesize    # => 6
Source
camelcase(io : IO, options : Unicode::CaseOptions = Unicode::CaseOptions::None, *, lower : Bool = false) : Nil

Writes an camelcased version of self to the given io.

If lower is true, lower camelcase will be written (the first letter is downcased).

io = IO::Memory.new
"eiffel_tower".camelcase io
io.to_s # => "EiffelTower"
Source
camelcase(options : Unicode::CaseOptions = Unicode::CaseOptions::None, *, lower : Bool = false) : String

Converts underscores to camelcase boundaries.

If lower is true, lower camelcase will be returned (the first letter is downcased).

"eiffel_tower".camelcase                                            # => "EiffelTower"
"empire_state_building".camelcase(lower: true)                      # => "empireStateBuilding"
"isolated_integer".camelcase(options: Unicode::CaseOptions::Turkic) # => "İsolatedİnteger"
Source
capitalize(options : Unicode::CaseOptions = :none) : String

Returns a new String with the first letter converted to uppercase and every subsequent letter converted to lowercase.

"hEllO".capitalize # => "Hello"
Source
capitalize(io : IO, options : Unicode::CaseOptions = :none) : Nil

Writes a capitalized version of self to the given io.

io = IO::Memory.new
"hEllO".capitalize io
io.to_s # => "Hello"
Source
center(len : Int, char : Char = ' ') : String

Adds instances of char to left and right of the string until it is at least size of len.

"Purple".center(8)      # => " Purple "
"Purple".center(8, '-') # => "-Purple-"
"Purple".center(9, '-') # => "-Purple--"
"Aubergine".center(8)   # => "Aubergine"
Source
center(io : IO, len : Int, char : Char = ' ') : Nil

Adds instances of char to left and right of the string until it is at least size of len, then appends the result to the given IO.

io = IO::Memory.new
"Purple".center(io, 9, '-')
io.to_s # => "-Purple--"
Source
char_at(index : Int) : Char

Returns the Char at the given index.

Negative indices can be used to start counting from the end of the string.

Raises IndexError if the index is out of bounds.

"hello".char_at(0)  # => 'h'
"hello".char_at(1)  # => 'e'
"hello".char_at(-1) # => 'o'
"hello".char_at(-2) # => 'l'
"hello".char_at(5)  # raises IndexError
Source
char_at(index : Int, &)

Returns the Char at the given index, or result of running the given block if out of bounds.

Negative indices can be used to start counting from the end of the string.

"hello".char_at(4) { 'x' }  # => 'o'
"hello".char_at(5) { 'x' }  # => 'x'
"hello".char_at(-1) { 'x' } # => 'o'
"hello".char_at(-5) { 'x' } # => 'h'
"hello".char_at(-6) { 'x' } # => 'x'
Source
char_index_to_byte_index(index)

Returns the byte index of a char index, or nil if out of bounds.

It is valid to pass #size to index, and in this case the answer will be the bytesize of this string.

"hello".char_index_to_byte_index(1) # => 1
"hello".char_index_to_byte_index(5) # => 5
"こんにちは".char_index_to_byte_index(1) # => 3
"こんにちは".char_index_to_byte_index(5) # => 15
Source
chars

Returns an Array of all characters in the string.

"ab☃".chars # => ['a', 'b', '☃']
Source
check_no_null_byte(name = nil) : self

Raises an ArgumentError if self has null bytes. Returns self otherwise.

This method should sometimes be called before passing a String to a C function.

Source
chomp(suffix : Char) : String

Returns a new String with suffix removed from the end of the string. If suffix is '\n' then "\r\n" is also removed if the string ends with it.

"hello".chomp('o') # => "hell"
"hello".chomp('a') # => "hello"
Source
chomp(suffix : String) : String

Returns a new String with suffix removed from the end of the string. If suffix is "\n" then "\r\n" is also removed if the string ends with it.

"hello".chomp("llo") # => "he"
"hello".chomp("ol")  # => "hello"
Source
chomp

Returns a new String with the last carriage return removed (that is, it will remove \n, \r, and \r\n).

"string\r\n".chomp # => "string"
"string\n\r".chomp # => "string\n"
"string\n".chomp   # => "string"
"string".chomp     # => "string"
"x".chomp.chomp    # => "x"
Source
clone

Returns self.

Source
codepoint_at(index) : Int32

Returns the codepoint of the character at the given index.

Negative indices can be used to start counting from the end of the string.

Raises IndexError if the index is out of bounds.

See also: Char#ord.

"hello".codepoint_at(0)  # => 104
"hello".codepoint_at(-1) # => 111
"hello".codepoint_at(5)  # raises IndexError
Source
codepoints

Returns an Array of the codepoints that make the string.

"ab☃".codepoints # => [97, 98, 9731]

See also: Char#ord.

Source
compare(other : String, case_insensitive = false, options : Unicode::CaseOptions = :none) : Int32

Compares this string with other, returning -1, 0 or 1 depending on whether this string is less, equal or greater than other, optionally in a case_insensitive manner.

Case-sensitive comparisons (case_insensitive == false) are equivalent to #<=> and are always done byte-per-byte.

"abcdef".compare("abcde")   # => 1
"abcdef".compare("abcdef")  # => 0
"abcdef".compare("abcdefg") # => -1
"abcdef".compare("ABCDEF")  # => 1

"abcdef".compare("ABCDEF", case_insensitive: true) # => 0
"abcdef".compare("ABCDEG", case_insensitive: true) # => -1

"heIIo".compare("heııo", case_insensitive: true, options: Unicode::CaseOptions::Turkic) # => 0
"Baffle".compare("baffle", case_insensitive: true, options: Unicode::CaseOptions::Fold)   # => 0

Case-sensitive only comparison is provided by the comparison operator #<=>.

Source
count

Yields each char in this string to the block, returns the number of times the block returned a truthy value.

"aabbcc".count &.in?('a', 'b') # => 4
Source
count(other : Char) : Int32

Counts the occurrences of other char in this string.

"aabbcc".count('a') # => 2
Source
count(*sets) : Int32

Sets should be a list of strings following the rules described at Char#in_set?. Returns the number of characters in this string that match the given set.

Source
delete

Yields each char in this string to the block. Returns a new String with all characters for which the block returned a truthy value removed.

"aabbcc".delete &.in?('a', 'b') # => "cc"
Source
delete(char : Char) : String

Returns a new String with all occurrences of char removed.

"aabbcc".delete('b') # => "aacc"
Source
delete(*sets) : String

Sets should be a list of strings following the rules described at Char#in_set?. Returns a new String with all characters that match the given set removed.

"aabbccdd".delete("a-c") # => "dd"
Source
delete_at(start : Int, count : Int) : String

Returns a new string that results from deleting count characters starting at start.

"abcdefg".delete_at(1, 3) # => "aefg"

Deleting more characters than those in the string is valid, and just results in deleting up to the last character:

"abcdefg".delete_at(3, 10) # => "abc"

A negative start counts from the end of the string:

"abcdefg".delete_at(-3, 2) # => "abcdg"

If count is negative, ArgumentError is raised.

If start is outside the bounds of the string, ArgumentError is raised.

However, start can be the position that is exactly the end of the string:

"abcd".delete_at(4, 3) # => "abcd"
Source
delete_at(range : Range) : String

Returns a new string that results from deleting characters at the given range.

"abcdef".delete_at(1..3) # => "aef"

Negative indices can be used to start counting from the end of the string:

"abcdef".delete_at(-3..-2) # => "abcf"

Raises IndexError if any index is outside the bounds of this string.

Source
delete_at(index : Int) : String

Returns a new string that results from deleting the character at the given index.

"abcde".delete_at(0) # => "bcde"
"abcde".delete_at(2) # => "abde"
"abcde".delete_at(4) # => "abcd"

A negative index counts from the end of the string:

"abcde".delete_at(-2) # => "abce"

If index is outside the bounds of the string, IndexError is raised.

Source
delete_at(*, index start : Int, count : Int) : String

Returns a new string that results from deleting count characters starting at start.

"abcdefg".delete_at(1, 3) # => "aefg"

Deleting more characters than those in the string is valid, and just results in deleting up to the last character:

"abcdefg".delete_at(3, 10) # => "abc"

A negative start counts from the end of the string:

"abcdefg".delete_at(-3, 2) # => "abcdg"

If count is negative, ArgumentError is raised.

If start is outside the bounds of the string, ArgumentError is raised.

However, start can be the position that is exactly the end of the string:

"abcd".delete_at(4, 3) # => "abcd"
Source
downcase(options : Unicode::CaseOptions = :none) : String

Returns a new String with each uppercase letter replaced with its lowercase counterpart.

"hEllO".downcase # => "hello"
Source
downcase(io : IO, options : Unicode::CaseOptions = :none) : Nil

Writes a downcased version of self to the given io.

io = IO::Memory.new
"hEllO".downcase io
io.to_s # => "hello"
Source
dump(io : IO) : Nil

Returns a representation of self as an ASCII-compatible Crystal string literal, wrapped in double quotes.

Non-printable characters (see Char#printable?) and non-ASCII characters (codepoints larger U+007F) are escaped.

"\u{1f48e} - à la carte\n".dump # => %("\\u{1F48E} - \\u00E0 la carte\\n")

See Char#unicode_escape for the format used to escape characters without a special escape sequence.

  • #dump_unquoted omits the delimiters.
  • #inspect only escapes non-printable characters.
Source
dump

Returns a representation of self as an ASCII-compatible Crystal string literal, wrapped in double quotes.

Non-printable characters (see Char#printable?) and non-ASCII characters (codepoints larger U+007F) are escaped.

"\u{1f48e} - à la carte\n".dump # => %("\\u{1F48E} - \\u00E0 la carte\\n")

See Char#unicode_escape for the format used to escape characters without a special escape sequence.

  • #dump_unquoted omits the delimiters.
  • #inspect only escapes non-printable characters.
Source
dump_unquoted

Returns a representation of self as the content of an ASCII-compatible Crystal string literal without delimiters.

Non-printable characters (see Char#printable?) and non-ASCII characters (codepoints larger U+007F) are escaped.

"\u{1f48e} - à la carte\n".dump_unquoted # => %(\\u{1F48E} - \\u00E0 la carte\\n)

See Char#unicode_escape for the format used to escape characters without a special escape sequence.

  • #dump wraps the content in double quotes.
  • #inspect_unquoted only escapes non-printable characters.
Source
dup

Returns self.

Source
each_byte

Yields each byte in the string to the block.

array = [] of UInt8
"ab☃".each_byte do |byte|
  array << byte
end
array # => [97, 98, 226, 152, 131]
Source
each_byte

Returns an Iterator over each byte in the string.

bytes = "ab☃".each_byte
bytes.next # => 97
bytes.next # => 98
bytes.next # => 226
bytes.next # => 152
bytes.next # => 131
Source
each_char

Yields each character in the string to the block.

array = [] of Char
"ab☃".each_char do |char|
  array << char
end
array # => ['a', 'b', '☃']
Source
each_char

Returns an Iterator over each character in the string.

chars = "ab☃".each_char
chars.next # => 'a'
chars.next # => 'b'
chars.next # => '☃'
Source
each_char_with_index(offset = 0, &)

Yields each character and its index in the string to the block.

array = [] of Tuple(Char, Int32)
"ab☃".each_char_with_index do |char, index|
  array << {char, index}
end
array # => [{'a', 0}, {'b', 1}, {'☃', 2}]

Accepts an optional offset parameter, which tells it to start counting from there.

Source
each_codepoint

Yields each codepoint to the block.

array = [] of Int32
"ab☃".each_codepoint do |codepoint|
  array << codepoint
end
array # => [97, 98, 9731]

See also: Char#ord.

Source
each_codepoint

Returns an Iterator for each codepoint.

codepoints = "ab☃".each_codepoint
codepoints.next # => 97
codepoints.next # => 98
codepoints.next # => 9731

See also: Char#ord.

Source
each_grapheme

Yields each Unicode extended grapheme cluster in this string.

Grapheme clusters correspond to "user-perceived characters" and are defined in Unicode Standard Annex #29. A cluster can consist of multiple code points which together form a single glyph.

"a👍🏼à".each_grapheme do |cluster|
  p! cluster
end
  • #graphemes collects all grapheme clusters in an array
Source
each_grapheme

Returns an iterator of this string split into Unicode extended grapheme clusters.

Grapheme clusters correspond to "user-perceived characters" and are defined in Unicode Standard Annex #29. A cluster can consist of multiple code points which together form a single glyph.

"a👍🏼à".each_grapheme.to_a # => [String::Grapheme('a'), String::Grapheme("👍🏼"), String::Grapheme("à")]
  • #graphemes collects all grapheme clusters in an array
Source
each_line(chomp : Bool = true, remove_empty : Bool = false, & : String -> ) : Nil

Splits the string after each newline and yields each line.

Both LF (line feed, \n) and CRLF (carriage return line feed, \r\n) are recognized as line delimiters.

If chomp is true, the line separator is removed from the end of each line.

"hello\nworld".each_line { }                   # yields "hello", "world"
"hello\nworld".each_line(chomp: false) { }     # yields "hello\n", "world"
"hello\nworld\r\n".each_line { }               # yields "hello", "world"
"hello\nworld\r\n".each_line(chomp: false) { } # yields "hello\n", "world\r\n"

If remove_empty is true, any empty lines are removed from the result.

A trailing line feed is not considered starting a final, empty line. The empty string does not contain any lines.

"hello\n".each_line { } # yields "hello"
"\n".each_line { }      # yields ""
"".each_line { }        # does not yield
  • #lines returns an array of lines
Source
each_line(chomp = true, *, remove_empty : Bool = false)

Returns an Iterator which yields each line of this string (see String#each_line).

Source
empty?

Returns true if this is the empty string, "".

Source
encode(encoding : String, invalid : Symbol | Nil = nil) : Bytes

Returns a slice of bytes containing this string encoded in the given encoding.

The invalid argument can be:

  • nil: an exception is raised on invalid byte sequences
  • :skip: invalid byte sequences are ignored
"好".encode("GB2312") # => Bytes[186, 195]
"好".bytes            # => [229, 165, 189]
Source
ends_with?(str : String) : Bool

Returns true if this string ends with the given str.

"hello".ends_with?("o")  # => true
"hello".ends_with?("lo") # => true
"hello".ends_with?("ll") # => false
Source
ends_with?(char : Char) : Bool

Returns true if this string ends with the given char.

"hello".ends_with?('o') # => true
"hello".ends_with?('l') # => false
Source
ends_with?(re : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Bool

Returns true if the regular expression re matches at the end of this string.

"22hello".ends_with?(/[0-9]/) # => false
"22hello".ends_with?(/[a-z]/) # => true
"22h".ends_with?(/[a-z]/)     # => true
"22h".ends_with?(/[A-Z]/)     # => false
"22h".ends_with?(/[a-z]{2}/)  # => false
"22hh".ends_with?(/[a-z]{2}/) # => true
Source
ensure_prefix(prefix : String | Char) : self

Returns self if it starts with the given prefix. Otherwise, returns a new String with the prefix prepended.

"llo!".ensure_prefix("He")   # => "Hello!"
"Hello!".ensure_prefix("He") # => "Hello!"
"ello".ensure_prefix('H')    # => "Hello!"
"Hello!".ensure_prefix('H')  # => "Hello!"
Source
ensure_suffix(suffix : String | Char) : self

Returns self if it ends with the given suffix. Otherwise, returns a new String with the suffix appended.

"Hell".ensure_suffix("o!")   # => "Hello!"
"Hello!".ensure_suffix("o!") # => "Hello!"
"Hello".ensure_suffix('!')   # => "Hello!"
"Hello!".ensure_suffix('!')  # => "Hello!"
Source
grapheme_size

Returns the number of Unicode extended graphemes clusters in this string.

  • #each_grapheme iterates the grapheme clusters.
Source
graphemes

Returns this string split into Unicode extended grapheme clusters.

Grapheme clusters correspond to "user-perceived characters" and are defined in Unicode Standard Annex #29. A cluster can consist of multiple code points which together form a single glyph.

"a👍🏼à".graphemes # => [String::Grapheme('a'), String::Grapheme("👍🏼"), String::Grapheme("à")]
  • #each_grapheme iterates the grapheme clusters without allocating an array
Source
gsub(string : String, &) : String

Returns a String where all occurrences of the given string are replaced with the block's value.

"hello yellow".gsub("ll") { "dd" } # => "heddo yeddow"
Source
gsub(pattern : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None, &) : String

Returns a String where all occurrences of the given pattern are replaced by the block value's value.

"hello".gsub(/./) { |s| s[0].ord.to_s + ' ' }                                              # => "104 101 108 108 111 "
"foo bar baz".gsub(/ba./) { |match| match.upcase }                                         # => "foo BAR BAZ"
"Name: Alice, Name: Bob".gsub(/Name: (\w+)/) { |full, matches| "User(#{matches[1]})" }     # => "User(Alice), User(Bob)"
"5x10, 3x7".gsub(/(\d+)x(\d+)/) { |full, matches| "#{matches[1].to_i * matches[2].to_i}" } # => "50, 21"
Source
gsub

Returns a String where each character yielded to the given block is replaced by the block's return value.

"hello".gsub { |char| char + 1 } # => "ifmmp"
"hello".gsub { "hi" }            # => "hihihihihi"
Source
gsub(char : Char, replacement) : String

Returns a String where all occurrences of the given char are replaced with the given replacement.

"hello".gsub('l', "lo")      # => "heloloo"
"hello world".gsub('o', 'a') # => "hella warld"
Source
gsub(pattern : Regex, hash : Hash(String, _) | NamedTuple, options : Regex::MatchOptions = Regex::MatchOptions::None) : String

Returns a String where all occurrences of the given pattern are replaced with a hash of replacements. If the hash contains the matched pattern, the corresponding value is used as a replacement. Otherwise the match is not included in the returned string.

# "he" and "l" are matched and replaced,
# but "o" is not and so is not included
"hello".gsub(/(he|l|o)/, {"he": "ha", "l": "la"}) # => "halala"
Source
gsub(string : String, replacement) : String

Returns a String where all occurrences of the given string are replaced with the given replacement.

"hello yellow".gsub("ll", "dd") # => "heddo yeddow"
Source
gsub(pattern : Regex, replacement, backreferences = true, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : String

Returns a String where all occurrences of the given pattern are replaced with the given replacement.

"hello".gsub(/[aeiou]/, '*') # => "h*ll*"

Within replacement, the special match variable $~ will not refer to the current match.

If backreferences is true (the default value), replacement can include backreferences:

"hello".gsub(/[aeiou]/, "(\\0)") # => "h(e)ll(o)"

When substitution is performed, any backreferences found in replacement will be replaced with the contents of the corresponding capture group in pattern. Backreferences to capture groups that were not present in pattern or that did not match will be skipped. See Regex for information about capture groups.

Backreferences are expressed in the form "\\d", where d is a group number, or "\\k<name>" where name is the name of a named capture group. A sequence of literal characters resembling a backreference can be expressed by placing "\\" before the sequence.

"foo".gsub(/o/, "x\\0x")                  # => "fxoxxox"
"foofoo".gsub(/(?<bar>oo)/, "|\\k<bar>|") # => "f|oo|f|oo|"
"foo".gsub(/o/, "\\\\0")                  # => "f\\0\\0"

Raises ArgumentError if an incomplete named back-reference is present in replacement.

Raises IndexError if a named group referenced in replacement is not present in pattern.

Source
gsub(hash : Hash(Char, _)) : String

Returns a String where all chars in the given hash are replaced by the corresponding hash values.

"hello".gsub({'e' => 'a', 'l' => 'd'}) # => "haddo"
Source
gsub(tuple : NamedTuple) : String

Returns a String where all chars in the given named tuple are replaced by the corresponding tuple values.

"hello".gsub({e: 'a', l: 'd'}) # => "haddo"
Source
has_back_references?

This returns true if this string has '\\' in it. It might not be a back reference, but '\\' is probably used for back references, so this check is faster than parsing the whole thing.

Source
hash(hasher)

See Object#hash(hasher)

Source
hexbytes

Interprets this string as containing a sequence of hexadecimal values and decodes it as a slice of bytes. Two consecutive bytes in the string represent a byte in the returned slice.

Raises ArgumentError if this string does not denote an hexstring.

"0102031aff".hexbytes  # => Bytes[1, 2, 3, 26, 255]
"1".hexbytes           # raises ArgumentError
"hello world".hexbytes # raises ArgumentError
Source
hexbytes?

Interprets this string as containing a sequence of hexadecimal values and decodes it as a slice of bytes. Two consecutive bytes in the string represent a byte in the returned slice.

Returns nil if this string does not denote an hexstring.

"0102031aff".hexbytes?  # => Bytes[1, 2, 3, 26, 255]
"1".hexbytes?           # => nil
"hello world".hexbytes? # => nil
Source
includes?(search : Char | String) : Bool

Returns true if the string contains search.

"Team".includes?('i')            # => false
"Dysfunctional".includes?("fun") # => true
Source
index(search : Char, offset = 0) : Int32 | Nil

Returns the index of the first occurrence of search in the string, or nil if not present. If offset is present, it defines the position to start the search.

"Hello, World".index('o')    # => 4
"Hello, World".index('Z')    # => nil
"Hello, World".index("o", 5) # => 8
"Hello, World".index("H", 2) # => nil
"Hello, World".index(/[ ]+/) # => 6
"Hello, World".index(/\d+/)  # => nil
Source
index(search : String, offset = 0)

Returns the index of the first occurrence of search in the string, or nil if not present. If offset is present, it defines the position to start the search.

"Hello, World".index('o')    # => 4
"Hello, World".index('Z')    # => nil
"Hello, World".index("o", 5) # => 8
"Hello, World".index("H", 2) # => nil
"Hello, World".index(/[ ]+/) # => 6
"Hello, World".index(/\d+/)  # => nil
Source
index(search : Regex, offset = 0, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Int32 | Nil

Returns the index of the first occurrence of search in the string, or nil if not present. If offset is present, it defines the position to start the search.

"Hello, World".index('o')    # => 4
"Hello, World".index('Z')    # => nil
"Hello, World".index("o", 5) # => 8
"Hello, World".index("H", 2) # => nil
"Hello, World".index(/[ ]+/) # => 6
"Hello, World".index(/\d+/)  # => nil
Source
index!(search, offset = 0) : Int32

Returns the index of the first occurrence of search in the string. If offset is present, it defines the position to start the search.

Raises Enumerable::NotFoundError if search does not occur in self.

"Hello, World".index!('o')    # => 4
"Hello, World".index!('Z')    # raises Enumerable::NotFoundError
"Hello, World".index!("o", 5) # => 8
"Hello, World".index!("H", 2) # raises Enumerable::NotFoundError
"Hello, World".index!(/[ ]+/) # => 6
"Hello, World".index!(/\d+/)  # raises Enumerable::NotFoundError
Source
index!(search : Regex, offset = 0, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Int32

Returns the index of the first occurrence of search in the string. If offset is present, it defines the position to start the search.

Raises Enumerable::NotFoundError if search does not occur in self.

"Hello, World".index!('o')    # => 4
"Hello, World".index!('Z')    # raises Enumerable::NotFoundError
"Hello, World".index!("o", 5) # => 8
"Hello, World".index!("H", 2) # raises Enumerable::NotFoundError
"Hello, World".index!(/[ ]+/) # => 6
"Hello, World".index!(/\d+/)  # raises Enumerable::NotFoundError
Source
insert(index : Int, other : Char) : String

Returns a new String that results of inserting other in self at index. Negative indices count from the end of the string, and insert after the given index.

Raises IndexError if the index is out of bounds.

"abcd".insert(0, 'X')  # => "Xabcd"
"abcd".insert(3, 'X')  # => "abcXd"
"abcd".insert(4, 'X')  # => "abcdX"
"abcd".insert(-3, 'X') # => "abXcd"
"abcd".insert(-1, 'X') # => "abcdX"

"abcd".insert(5, 'X')  # raises IndexError
"abcd".insert(-6, 'X') # raises IndexError
Source
insert(index : Int, other : String) : String

Returns a new String that results of inserting other in self at index. Negative indices count from the end of the string, and insert after the given index.

Raises IndexError if the index is out of bounds.

"abcd".insert(0, "FOO")  # => "FOOabcd"
"abcd".insert(3, "FOO")  # => "abcFOOd"
"abcd".insert(4, "FOO")  # => "abcdFOO"
"abcd".insert(-3, "FOO") # => "abFOOcd"
"abcd".insert(-1, "FOO") # => "abcdFOO"

"abcd".insert(5, "FOO")  # raises IndexError
"abcd".insert(-6, "FOO") # raises IndexError
Source
inspect(io : IO) : Nil

Returns a representation of self as a Crystal string literal, wrapped in double quotes.

Non-printable characters (see Char#printable?) are escaped.

"\u{1f48e} - à la carte\n".inspect # => %("\u{1F48E} - à la carte\\n")

See Char#unicode_escape for the format used to escape characters without a special escape sequence.

  • #inspect_unquoted omits the delimiters.
  • #dump additionally escapes all non-ASCII characters.
Source
inspect

Returns a representation of self as a Crystal string literal, wrapped in double quotes.

Non-printable characters (see Char#printable?) are escaped.

"\u{1f48e} - à la carte\n".inspect # => %("\u{1F48E} - à la carte\\n")

See Char#unicode_escape for the format used to escape characters without a special escape sequence.

  • #inspect_unquoted omits the delimiters.
  • #dump additionally escapes all non-ASCII characters.
Source
inspect_unquoted(io : IO) : Nil

Returns a representation of self as the content of a Crystal string literal without delimiters.

Non-printable characters (see Char#printable?) are escaped.

"\u{1f48e} - à la carte\n".inspect_unquoted # => %(\u{1F48E} - à la carte\\n)

See Char#unicode_escape for the format used to escape characters without a special escape sequence.

  • #inspect wraps the content in double quotes.
  • #dump_unquoted additionally escapes all non-ASCII characters.
Source
inspect_unquoted

Returns a representation of self as the content of a Crystal string literal without delimiters.

Non-printable characters (see Char#printable?) are escaped.

"\u{1f48e} - à la carte\n".inspect_unquoted # => %(\u{1F48E} - à la carte\\n)

See Char#unicode_escape for the format used to escape characters without a special escape sequence.

  • #inspect wraps the content in double quotes.
  • #dump_unquoted additionally escapes all non-ASCII characters.
Source
lchop(prefix : Char | String) : String

Returns a new String with prefix removed from the beginning of the string.

"hello".lchop('h')   # => "ello"
"hello".lchop('g')   # => "hello"
"hello".lchop("hel") # => "lo"
"hello".lchop("eh")  # => "hello"
Source
lchop

Returns a new String with the first char removed from it. Applying lchop to an empty string returns an empty string.

"hello".lchop # => "ello"
"".lchop      # => ""
Source
lchop?(prefix : Char | String) : String | Nil

Returns a new String with prefix removed from the beginning of the string if possible, else returns nil.

"hello".lchop?('h')   # => "ello"
"hello".lchop?('g')   # => nil
"hello".lchop?("hel") # => "lo"
"hello".lchop?("eh")  # => nil
Source
lchop?

Returns a new String with the first char removed from it if possible, else returns nil.

"hello".lchop? # => "ello"
"".lchop?      # => nil
Source
lines(chomp : Bool = true) : Array(String)

Returns an array of the string split into lines.

Both LF (line feed, \n) and CRLF (carriage return line feed, \r\n) are recognized as line delimiters.

If chomp is true, the line separator is removed from the end of each line.

"hello\nworld\n".lines                 # => ["hello", "world"]
"hello\nworld\n".lines(chomp: false)   # => ["hello\n", "world\n"]
"hello\nworld\r\n".lines               # => ["hello", "world"]
"hello\nworld\r\n".lines(chomp: false) # => ["hello\n", "world\r\n"]

A trailing line feed is not considered starting a final, empty line. The empty string does not contain any lines.

"hellp\n".lines # => ["hellp"]
"\n".lines      # => [""]
"".lines        # => [] of String
  • #each_line yields each line without allocating an array
Source
ljust(len : Int, char : Char = ' ') : String

Adds instances of char to right of the string until it is at least size of len.

"Purple".ljust(8)      # => "Purple  "
"Purple".ljust(8, '-') # => "Purple--"
"Aubergine".ljust(8)   # => "Aubergine"
Source
ljust(io : IO, len : Int, char : Char = ' ') : Nil

Adds instances of char to right of the string until it is at least size of len, and then appends the result to the given IO.

io = IO::Memory.new
"Purple".ljust(io, 8, '-')
io.to_s # => "Purple--"
Source
lstrip(char : Char) : String

Returns a new string with leading occurrences of char removed.

"aaabcdaaa".lstrip('a') # => "bcdaaa"
Source
lstrip(chars : String) : String

Returns a new string where leading occurrences of any char in chars are removed. The chars argument is not a suffix; rather; all combinations of its values are stripped.

"bcadefcba".lstrip("abc") # => "defcba"
Source
lstrip

Returns a new String with leading whitespace removed.

"    hello    ".lstrip # => "hello    "
"\tgoodbye\r\n".lstrip # => "goodbye\r\n"
Source
lstrip

Returns a new string where leading characters for which the block returns a truthy value are removed.

"bcadefcba".lstrip { |c| 'a' <= c <= 'c' } # => "defcba"
Source
match(regex : Regex, pos = 0, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Regex::MatchData | Nil

Finds matches of regex starting at pos and updates $~ to the result.

"foo".match(/foo/) # => Regex::MatchData("foo")
$~                 # => Regex::MatchData("foo")

"foo".match(/bar/) # => nil
$~                 # raises Exception
Source
match!(regex : Regex, pos = 0, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Regex::MatchData

Finds matches of regex starting at pos and updates $~ to the result. Raises Regex::Error if there are no matches.

"foo".match!(/foo/) # => Regex::MatchData("foo")
$~                  # => Regex::MatchData("foo")

"foo".match!(/bar/) # => raises Exception
Source
match_full(regex : Regex) : Regex::MatchData | Nil

Matches the regular expression regex against the entire string and returns the resulting MatchData. It also updates $~ with the result.

"foo".match_full(/foo/)  # => Regex::MatchData("foo")
$~                       # => Regex::MatchData("foo")
"fooo".match_full(/foo/) # => nil
$~                       # raises Exception
Source
match_full!(regex : Regex) : Regex::MatchData

Matches the regular expression regex against the entire string and returns the resulting MatchData. It also updates $~ with the result. Raises Regex::Error if there are no matches.

"foo".match_full!(/foo/)  # => Regex::MatchData("foo")
$~                        # => Regex::MatchData("foo")
"fooo".match_full!(/foo/) # Regex::Error
$~                        # raises Exception
Source
matches?(regex : Regex, pos = 0, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Bool

Finds match of regex like #match, but it returns Bool value. It neither returns MatchData nor assigns it to the $~ variable.

"foo".matches?(/bar/) # => false
"foo".matches?(/foo/) # => true

# `$~` is not set even if last match succeeds.
$~ # raises Exception
Source
matches_full?(regex : Regex) : Bool

Returns true if the regular expression regex matches this string entirely.

"foo".matches_full?(/foo/)  # => true
"fooo".matches_full?(/foo/) # => false

# `$~` is not set even if last match succeeds.
$~ # raises Exception
Source
partition(search : Char | String) : Tuple(String, String, String)

Searches separator or pattern (Regex) in the string, and returns a Tuple with the part before it, the match, and the part after it. If it is not found, returns str followed by two empty strings.

"hello".partition("l") # => {"he", "l", "lo"}
"hello".partition("x") # => {"hello", "", ""}
Source
partition(search : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Tuple(String, String, String)

Searches separator or pattern (Regex) in the string, and returns a Tuple with the part before it, the match, and the part after it. If it is not found, returns str followed by two empty strings.

"hello".partition("l") # => {"he", "l", "lo"}
"hello".partition("x") # => {"hello", "", ""}
Source
presence

Returns self unless #blank? is true in which case it returns nil.

"a".presence         # => "a"
"".presence          # => nil
"   ".presence       # => nil
"    a    ".presence # => "    a    "
nil.presence         # => nil

config = {"empty" => ""}
config["empty"]?.presence || "default"   # => "default"
config["missing"]?.presence || "default" # => "default"

See also: Nil#presence.

Source
present?

Returns true if this string is not #blank?.

Source
pretty_print(pp : PrettyPrint) : Nil

Pretty prints self into the given printer.

Source
rchop(suffix : Char | String) : String

Returns a new String with suffix removed from the end of the string.

"strings".rchop('s')  # => "string"
"string".rchop('x')   # => "string"
"string".rchop("ing") # => "str"
"string".rchop("inx") # => "string"
Source
rchop

Returns a new String with the last character removed. Applying rchop to an empty string returns an empty string.

"string\r\n".rchop # => "string\r"
"string\n\r".rchop # => "string\n"
"string\n".rchop   # => "string"
"strings".rchop    # => "string"
"x".rchop.rchop    # => ""
Source
rchop?(suffix : Char | String) : String | Nil

Returns a new String with suffix removed from the end of the string if possible, else returns nil.

"strings".rchop?('s')  # => "string"
"string".rchop?('x')   # => nil
"string".rchop?("ing") # => "str"
"string".rchop?("inx") # => nil
Source
rchop?

Returns a new String with the last character removed if possible, else returns nil.

"string\r\n".rchop? # => "string\r"
"string\n\r".rchop? # => "string\n"
"string\n".rchop?   # => "string"
"strings".rchop?    # => "string"
"".rchop?           # => nil
Source
reverse

Reverses the order of characters in the string.

"Argentina".reverse # => "anitnegrA"
"racecar".reverse   # => "racecar"

Works on Unicode graphemes (and not codepoints) so combining characters are preserved.

"Noe\u0308l".reverse # => "lëoN"
Source
rindex(search : Char, offset = size - 1)

Returns the index of the last appearance of search in the string, If offset is present, it defines the position to end the search (characters beyond this point are ignored).

"Hello, World".rindex('o')    # => 8
"Hello, World".rindex('Z')    # => nil
"Hello, World".rindex('o', 5) # => 4
"Hello, World".rindex('W', 2) # => nil
Source
rindex(search : String, offset = size - search.size) : Int32 | Nil

Returns the index of the last appearance of search in the string, If offset is present, it defines the position to end the search (characters beyond this point are ignored).

"Hello, World".rindex("orld")    # => 8
"Hello, World".rindex("snorlax") # => nil
"Hello, World".rindex("o", 5)    # => 4
"Hello, World".rindex("W", 2)    # => nil
Source
rindex(search : Regex, offset = size, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Int32 | Nil

Returns the index of the last appearance of search in the string, If offset is present, it defines the position to end the search (characters beyond this point are ignored).

"Hello, World".rindex(/world/i) # => 7
"Hello, World".rindex(/world/)  # => nil
"Hello, World".rindex(/o/, 5)   # => 4
"Hello, World".rindex(/W/, 2)   # => nil
Source
rindex!(search : Char, offset = size - 1) : Int32

Returns the index of the last appearance of search in the string, If offset is present, it defines the position to end the search (characters beyond this point are ignored). Raises Enumerable::NotFoundError if search does not occur in self.

"Hello, World".rindex!('o')    # => 8
"Hello, World".rindex!('Z')    # raises Enumerable::NotFoundError
"Hello, World".rindex!('o', 5) # => 4
"Hello, World".rindex!('W', 2) # raises Enumerable::NotFoundError
Source
rindex!(search : String, offset = size - search.size) : Int32

Returns the index of the last appearance of search in the string, If offset is present, it defines the position to end the search (characters beyond this point are ignored). Raises Enumerable::NotFoundError if search does not occur in self.

"Hello, World".rindex!("orld")    # => 8
"Hello, World".rindex!("snorlax") # raises Enumerable::NotFoundError
"Hello, World".rindex!("o", 5)    # => 4
"Hello, World".rindex!("W", 2)    # raises Enumerable::NotFoundError
Source
rindex!(search : Regex, offset = size, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Int32

Returns the index of the last appearance of search in the string, If offset is present, it defines the position to end the search (characters beyond this point are ignored). Raises Enumerable::NotFoundError if search does not occur in self.

"Hello, World".rindex!(/world/i) # => 7
"Hello, World".rindex!(/world/)  # raises Enumerable::NotFoundError
"Hello, World".rindex!(/o/, 5)   # => 4
"Hello, World".rindex!(/W/, 2)   # raises Enumerable::NotFoundError
Source
rjust(len : Int, char : Char = ' ') : String

Adds instances of char to left of the string until it is at least size of len.

"Purple".rjust(8)      # => "  Purple"
"Purple".rjust(8, '-') # => "--Purple"
"Aubergine".rjust(8)   # => "Aubergine"
Source
rjust(io : IO, len : Int, char : Char = ' ') : Nil

Adds instances of char to left of the string until it is at least size of len, and then appends the result to the given IO.

io = IO::Memory.new
"Purple".rjust(io, 8, '-')
io.to_s # => "--Purple"
Source
rpartition(search : Char | String) : Tuple(String, String, String)

Searches separator or pattern (Regex) in the string from the end of the string, and returns a Tuple with the part before it, the match, and the part after it. If it is not found, returns two empty strings and str.

"hello".rpartition("l")  # => {"hel", "l", "o"}
"hello".rpartition("x")  # => {"", "", "hello"}
"hello".rpartition(/.l/) # => {"he", "ll", "o"}
Source
rpartition(search : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Tuple(String, String, String)

Searches separator or pattern (Regex) in the string from the end of the string, and returns a Tuple with the part before it, the match, and the part after it. If it is not found, returns two empty strings and str.

"hello".rpartition("l")  # => {"hel", "l", "o"}
"hello".rpartition("x")  # => {"", "", "hello"}
"hello".rpartition(/.l/) # => {"he", "ll", "o"}
Source
rstrip(char : Char) : String

Returns a new string with trailing occurrences of char removed.

"aaabcdaaa".rstrip('a') # => "aaabcd"
Source
rstrip(chars : String) : String

Returns a new string where trailing occurrences of any char in chars are removed. The chars argument is not a suffix; rather; all combinations of its values are stripped.

"abcdefcba".rstrip("abc") # => "abcdef"
Source
rstrip

Returns a new String with trailing whitespace removed.

"    hello    ".rstrip # => "    hello"
"\tgoodbye\r\n".rstrip # => "\tgoodbye"
Source
rstrip

Returns a new string where trailing characters for which the block returns a truthy value are removed.

"bcadefcba".rstrip { |c| 'a' <= c <= 'c' } # => "bcadef"
Source
scan(pattern : String, &) : self

Searches the string for instances of pattern, yielding the matched string for each match.

Source
scan(pattern : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None, &) : self

Searches the string for instances of pattern, yielding a Regex::MatchData for each match.

Source
scan(pattern : String) : Array(String)

Searches the string for instances of pattern, returning an array of the matched string for each match.

Source
scan(pattern : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Array(Regex::MatchData)

Searches the string for instances of pattern, returning an Array of Regex::MatchData for each match.

Source
scrub(replacement = Char::REPLACEMENT) : String

Returns a String where bytes that are invalid in the UTF-8 encoding are replaced with replacement.

Source
size

Returns the number of unicode codepoints in this string.

"hello".size # => 5
"你好".size    # => 2
Source
split(limit : Int32 | Nil = nil) : Array(String)

Makes an array by splitting the string on any amount of ASCII whitespace characters (and removing that whitespace).

If limit is present, up to limit new strings will be created, with the entire remainder added to the last string.

old_pond = "
  Old pond
  a frog leaps in
  water's sound
"
old_pond.split    # => ["Old", "pond", "a", "frog", "leaps", "in", "water's", "sound"]
old_pond.split(3) # => ["Old", "pond", "a frog leaps in\n  water's sound\n"]
Source
split(limit : Int32 | Nil = nil, &block : String -> _)

Splits the string after any amount of ASCII whitespace characters and yields each non-whitespace part to a block.

If limit is present, up to limit new strings will be created, with the entire remainder added to the last string.

ary = [] of String
old_pond = "
  Old pond
  a frog leaps in
  water's sound
"

old_pond.split { |s| ary << s }
ary # => ["Old", "pond", "a", "frog", "leaps", "in", "water's", "sound"]
ary.clear

old_pond.split(3) { |s| ary << s }
ary # => ["Old", "pond", "a frog leaps in\n  water's sound\n"]
Source
split(separator : Char, limit = nil, *, remove_empty = false) : Array(String)

Makes an Array by splitting the string on the given character separator (and removing that character).

If limit is present, up to limit new strings will be created, with the entire remainder added to the last string.

If remove_empty is true, any empty strings are removed from the result.

"foo,,bar,baz".split(',')                     # => ["foo", "", "bar", "baz"]
"foo,,bar,baz".split(',', remove_empty: true) # => ["foo", "bar", "baz"]
"foo,bar,baz".split(',', 2)                   # => ["foo", "bar,baz"]
Source
split(separator : Char, limit = nil, *, remove_empty = false, &block : String -> _)

Splits the string after each character separator and yields each part to a block.

If limit is present, up to limit new strings will be created, with the entire remainder added to the last string.

If remove_empty is true, any empty strings are not yielded.

ary = [] of String

"foo,,bar,baz".split(',') { |string| ary << string }
ary # => ["foo", "", "bar", "baz"]
ary.clear

"foo,,bar,baz".split(',', remove_empty: true) { |string| ary << string }
ary # => ["foo", "bar", "baz"]
ary.clear

"foo,bar,baz".split(',', 2) { |string| ary << string }
ary # => ["foo", "bar,baz"]
Source
split(separator : String, limit = nil, *, remove_empty = false) : Array(String)

Makes an Array by splitting the string on separator (and removing instances of separator).

If limit is present, the array will be limited to limit items and the final item will contain the remainder of the string.

If separator is an empty string (""), the string will be separated into one-character strings.

If remove_empty is true, any empty strings are removed from the result.

long_river_name = "Mississippi"
long_river_name.split("ss")                    # => ["Mi", "i", "ippi"]
long_river_name.split("i")                     # => ["M", "ss", "ss", "pp", ""]
long_river_name.split("i", remove_empty: true) # => ["M", "ss", "ss", "pp"]
long_river_name.split("")                      # => ["M", "i", "s", "s", "i", "s", "s", "i", "p", "p", "i"]
Source
split(separator : String, limit = nil, *, remove_empty = false, &block : String -> _)

Splits the string after each string separator and yields each part to a block.

If limit is present, the array will be limited to limit items and the final item will contain the remainder of the string.

If separator is an empty string (""), the string will be separated into one-character strings.

If remove_empty is true, any empty strings are removed from the result.

ary = [] of String
long_river_name = "Mississippi"

long_river_name.split("ss") { |s| ary << s }
ary # => ["Mi", "i", "ippi"]
ary.clear

long_river_name.split("i") { |s| ary << s }
ary # => ["M", "ss", "ss", "pp", ""]
ary.clear

long_river_name.split("i", remove_empty: true) { |s| ary << s }
ary # => ["M", "ss", "ss", "pp"]
ary.clear

long_river_name.split("") { |s| ary << s }
ary # => ["M", "i", "s", "s", "i", "s", "s", "i", "p", "p", "i"]
Source
split(separator : Regex, limit = nil, *, remove_empty = false, options : Regex::MatchOptions = Regex::MatchOptions::None) : Array(String)

Makes an Array by splitting the string on separator (and removing instances of separator).

If separator is an empty regex (//), the string will be separated into one-character strings. If separator defines any capture groups, their matches are also included in the result.

If limit is present, separator will be matched at most limit - 1 times, and the final item will contain the remainder of the string. The array may contain more than limit items if capture groups are present.

If remove_empty is true, any empty strings are removed from the result. This does not affect matches from separator's capture groups.

long_river_name = "Mississippi"
long_river_name.split(/s+/)  # => ["Mi", "i", "ippi"]
long_river_name.split(//)    # => ["M", "i", "s", "s", "i", "s", "s", "i", "p", "p", "i"]
long_river_name.split(/(i)/) # => ["M", "i", "ss", "i", "ss", "i", "pp", "i", ""]
Source
split(separator : Regex, limit = nil, *, remove_empty = false, options : Regex::MatchOptions = Regex::MatchOptions::None, &block : String -> _)

Splits the string after each regex separator and yields each part to a block.

If separator is an empty regex (//), the string will be separated into one-character strings. If separator defines any capture groups, their matches are also yielded in order.

If limit is present, separator will be matched at most limit - 1 times, and the final item will contain the remainder of the string. More than limit items may be yielded in total if capture groups are present.

If remove_empty is true, any empty strings are not yielded. This does not affect matches from separator's capture groups.

ary = [] of String
long_river_name = "Mississippi"

long_river_name.split(/s+/) { |s| ary << s }
ary # => ["Mi", "i", "ippi"]
ary.clear

long_river_name.split(//) { |s| ary << s }
ary # => ["M", "i", "s", "s", "i", "s", "s", "i", "p", "p", "i"]
ary.clear

long_river_name.split(/(i)/) { |s| ary << s }
ary # => ["M", "i", "ss", "i", "ss", "i", "pp", "i", ""]
Source
squeeze

Yields each char in this string to the block. Returns a new String, that has all characters removed, that were the same as the previous one and for which the given block returned a truthy value.

"aaabbbccc".squeeze &.in?('a', 'b') # => "abccc"
"aaabbbccc".squeeze &.in?('a', 'c') # => "abbbc"
Source
squeeze(char : Char) : String

Returns a new String, with all runs of char replaced by one instance.

"a    bbb".squeeze(' ') # => "a bbb"
Source
squeeze

Returns a new String, that has all characters removed, that were the same as the previous one.

"a       bbb".squeeze # => "a b"
Source
squeeze(*sets : String) : String

Sets should be a list of strings following the rules described at Char#in_set?. Returns a new String with all runs of the same character replaced by one instance, if they match the given set.

If no set is given, all characters are matched.

"aaabbbcccddd".squeeze("b-d") # => "aaabcd"
"a       bbb".squeeze         # => "a b"
Source
starts_with?(str : String) : Bool

Returns true if this string starts with the given str.

"hello".starts_with?("h")  # => true
"hello".starts_with?("he") # => true
"hello".starts_with?("hu") # => false
Source
starts_with?(char : Char) : Bool

Returns true if this string starts with the given char.

"hello".starts_with?('h') # => true
"hello".starts_with?('e') # => false
Source
starts_with?(re : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Bool

Returns true if the regular expression re matches at the start of this string.

"22hello".starts_with?(/[0-9]/) # => true
"22hello".starts_with?(/[a-z]/) # => false
"h22".starts_with?(/[a-z]/)     # => true
"h22".starts_with?(/[A-Z]/)     # => false
"h22".starts_with?(/[a-z]{2}/)  # => false
"hh22".starts_with?(/[a-z]{2}/) # => true
Source
strip(char : Char) : String

Returns a new string where leading and trailing occurrences of char are removed.

"aaabcdaaa".strip('a') # => "bcd"
Source
strip(chars : String) : String

Returns a new string where leading and trailing occurrences of any char in chars are removed. The chars argument is not a prefix or suffix; rather; all combinations of its values are stripped.

"abcdefcba".strip("abc") # => "def"
Source
strip

Returns a new String with leading and trailing whitespace removed.

"    hello    ".strip # => "hello"
"\tgoodbye\r\n".strip # => "goodbye"
Source
strip

Returns a new string where leading and trailing characters for which the block returns a truthy value are removed.

"bcadefcba".strip { |c| 'a' <= c <= 'c' } # => "def"
Source
sub(string : String, &) : String

Returns a String where the first occurrences of the given string is replaced with the block's value.

"hello yellow".sub("ll") { "dd" } # => "heddo yellow"
Source
sub(pattern : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None, &) : String

Returns a String where the first occurrence of pattern is replaced by the block's return value.

"hello".sub(/./) { |s| s[0].ord.to_s + ' ' } # => "104 ello"
Source
sub

Returns a new String where the first character is yielded to the given block and replaced by its return value.

"hello".sub { |char| char + 1 } # => "iello"
"hello".sub { "hi" }            # => "hiello"
Source
sub(char : Char, replacement) : String

Returns a String where the first occurrence of char is replaced by replacement.

"hello".sub('l', "lo")      # => "helolo"
"hello world".sub('o', 'a') # => "hella world"
Source
sub(pattern : Regex, hash : Hash(String, _) | NamedTuple, options : Regex::MatchOptions = Regex::MatchOptions::None) : String

Returns a String where the first occurrences of the given pattern is replaced with the matching entry from the hash of replacements. If the first match is not included in the hash, nothing is replaced.

"hello".sub(/(he|l|o)/, {"he": "ha", "l": "la"}) # => "hallo"
"hello".sub(/(he|l|o)/, {"l": "la"})             # => "hello"
Source
sub(string : String, replacement) : String

Returns a String where the first occurrences of the given string is replaced with the given replacement.

"hello yellow".sub("ll", "dd") # => "heddo yellow"
Source
sub(index : Int, replacement : Char) : String

Returns a new String with the character at the given index replaced by replacement.

"hello".sub(1, 'a') # => "hallo"
Source
sub(index : Int, replacement : String) : String

Returns a new String with the character at the given index replaced by replacement.

"hello".sub(1, "eee") # => "heeello"
Source
sub(range : Range, replacement : Char) : String

Returns a new String with characters at the given range replaced by replacement.

"hello".sub(1..2, 'a') # => "halo"
Source
sub(range : Range, replacement : String) : String

Returns a new String with characters at the given range replaced by replacement.

"hello".sub(1..2, "eee") # => "heeelo"
Source
sub(pattern : Regex, replacement, backreferences = true, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : String

Returns a String where the first occurrence of pattern is replaced by replacement

"hello".sub(/[aeiou]/, "*") # => "h*llo"

Within replacement, the special match variable $~ will not refer to the current match.

If backreferences is true (the default value), replacement can include backreferences:

"hello".sub(/[aeiou]/, "(\\0)") # => "h(e)llo"

When substitution is performed, any backreferences found in replacement will be replaced with the contents of the corresponding capture group in pattern. Backreferences to capture groups that were not present in pattern or that did not match will be skipped. See Regex for information about capture groups.

Backreferences are expressed in the form "\\d", where d is a group number, or "\\k&lt;name>" where name is the name of a named capture group. A sequence of literal characters resembling a backreference can be expressed by placing "\\" before the sequence.

"foo".sub(/o/, "x\\0x")                  # => "fxoxo"
"foofoo".sub(/(?<bar>oo)/, "|\\k<bar>|") # => "f|oo|foo"
"foo".sub(/o/, "\\\\0")                  # => "f\\0o"

Raises ArgumentError if an incomplete named back-reference is present in replacement.

Raises IndexError if a named group referenced in replacement is not present in pattern.

Source
sub(hash : Hash(Char, _)) : String

Returns a String where the first char in the string matching a key in the given hash is replaced by the corresponding hash value.

"hello".sub({'a' => 'b', 'l' => 'd'}) # => "hedlo"
Source
succ

Returns the successor of the string. The successor is calculated by incrementing characters starting from the rightmost alphanumeric (or the rightmost character if there are no alphanumerics) in the string. Incrementing a digit always results in another digit, and incrementing a letter results in another letter of the same case.

If the increment generates a "carry", the character to the left of it is incremented. This process repeats until there is no carry, adding an additional character if necessary.

"abcd".succ      # => "abce"
"THX1138".succ   # => "THX1139"
"((koala))".succ # => "((koalb))"
"1999zzz".succ   # => "2000aaa"
"ZZZ9999".succ   # => "AAAA0000"
"***".succ       # => "**+"
Source
titleize(io : IO, options : Unicode::CaseOptions = :none, *, underscore_to_space : Bool = false) : Nil

Writes a titleized version of self to the given io. Optionally, if underscore_to_space is true, underscores (_) will be converted to a space and the following letter converted to uppercase.

io = IO::Memory.new
"x-men: the last stand".titleize io
io.to_s # => "X-men: The Last Stand"
Source
titleize(options : Unicode::CaseOptions = :none, *, underscore_to_space : Bool = false) : String

Returns a new String with the first letter after any space converted to uppercase and every other letter converted to lowercase. Optionally, if underscore_to_space is true, underscores (_) will be converted to a space and the following letter converted to uppercase.

"hEllO tAb\tworld".titleize                   # => "Hello Tab\tWorld"
"  spaces before".titleize                    # => "  Spaces Before"
"x-men: the last stand".titleize              # => "X-men: The Last Stand"
"foo_bar".titleize                            # => "Foo_bar"
"foo_bar".titleize(underscore_to_space: true) # => "Foo Bar"
Source
to_big_d

Converts self to BigDecimal.

require "big"
"1212341515125412412412421".to_big_d
Source
to_big_f

Converts self to a BigFloat.

require "big"
"1234.0".to_big_f
Source
to_big_i(base : Int32 = 10) : BigInt

Returns a BigInt from this string, in the given base.

Raises ArgumentError if this string doesn't denote a valid integer.

require "big"

"3a060dbf8d1a5ac3e67bc8f18843fc48".to_big_i(16)
Source
to_f(whitespace : Bool = true, strict : Bool = true) : Float64

Returns the result of interpreting characters in this string as a floating point number (Float64). This method raises an exception if the string is not a valid float representation or exceeds the range of the data type. Values representing infinity or NaN are considered valid.

Options:

  • whitespace: if true, leading and trailing whitespaces are allowed
  • strict: if true, extraneous characters past the end of the number are disallowed, unless whitespace is also true and all the trailing characters past the number are whitespaces
"123.45e1".to_f                # => 1234.5
"45.67 degrees".to_f           # raises ArgumentError
"thx1138".to_f(strict: false)  # raises ArgumentError
" 1.2".to_f(whitespace: false) # raises ArgumentError
"1.2foo".to_f(strict: false)   # => 1.2
Source
to_f32(whitespace : Bool = true, strict : Bool = true) : Float32

Same as #to_f but returns a Float32.

Source
to_f32?(whitespace : Bool = true, strict : Bool = true) : Float32 | Nil

Same as #to_f? but returns a Float32.

Source
to_f64(whitespace : Bool = true, strict : Bool = true) : Float64

Returns the result of interpreting characters in this string as a floating point number (Float64). This method raises an exception if the string is not a valid float representation or exceeds the range of the data type. Values representing infinity or NaN are considered valid.

Options:

  • whitespace: if true, leading and trailing whitespaces are allowed
  • strict: if true, extraneous characters past the end of the number are disallowed, unless whitespace is also true and all the trailing characters past the number are whitespaces
"123.45e1".to_f                # => 1234.5
"45.67 degrees".to_f           # raises ArgumentError
"thx1138".to_f(strict: false)  # raises ArgumentError
" 1.2".to_f(whitespace: false) # raises ArgumentError
"1.2foo".to_f(strict: false)   # => 1.2
Source
to_f64?(whitespace : Bool = true, strict : Bool = true) : Float64 | Nil

Returns the result of interpreting characters in this string as a floating point number (Float64). This method returns nil if the string is not a valid float representation or exceeds the range of the data type. Values representing infinity or NaN are considered valid.

Options:

  • whitespace: if true, leading and trailing whitespaces are allowed
  • strict: if true, extraneous characters past the end of the number are disallowed, unless whitespace is also true and all the trailing characters past the number are whitespaces
"123.45e1".to_f?                # => 1234.5
"45.67 degrees".to_f?           # => nil
"thx1138".to_f?                 # => nil
" 1.2".to_f?(whitespace: false) # => nil
"1.2foo".to_f?(strict: false)   # => 1.2
Source
to_f?(whitespace : Bool = true, strict : Bool = true) : Float64 | Nil

Returns the result of interpreting characters in this string as a floating point number (Float64). This method returns nil if the string is not a valid float representation or exceeds the range of the data type. Values representing infinity or NaN are considered valid.

Options:

  • whitespace: if true, leading and trailing whitespaces are allowed
  • strict: if true, extraneous characters past the end of the number are disallowed, unless whitespace is also true and all the trailing characters past the number are whitespaces
"123.45e1".to_f?                # => 1234.5
"45.67 degrees".to_f?           # => nil
"thx1138".to_f?                 # => nil
" 1.2".to_f?(whitespace: false) # => nil
"1.2foo".to_f?(strict: false)   # => 1.2
Source
to_i(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false)

Returns the result of interpreting leading characters in this string as an integer base base (between 2 and 36).

If there is not a valid number at the start of this string, or if the resulting integer doesn't fit an Int32, an ArgumentError is raised.

Options:

  • whitespace: if true, leading and trailing whitespaces are allowed
  • underscore: if true, underscores in numbers are allowed
  • prefix: if true, the prefixes "0x", "0o" and "0b" override the base
  • strict: if true, extraneous characters past the end of the number are disallowed, unless whitespace is also true and all the trailing characters past the number are whitespaces
  • leading_zero_is_octal: if true, then a number prefixed with "0" will be treated as an octal
"12345".to_i             # => 12345
"0a".to_i                # raises ArgumentError
"hello".to_i             # raises ArgumentError
"0a".to_i(16)            # => 10
"1100101".to_i(2)        # => 101
"1100101".to_i(8)        # => 294977
"1100101".to_i(10)       # => 1100101
"1100101".to_i(base: 16) # => 17826049

"12_345".to_i                   # raises ArgumentError
"12_345".to_i(underscore: true) # => 12345

"  12345  ".to_i                    # => 12345
"  12345  ".to_i(whitespace: false) # raises ArgumentError

"0x123abc".to_i               # raises ArgumentError
"0x123abc".to_i(prefix: true) # => 1194684

"99 red balloons".to_i                # raises ArgumentError
"99 red balloons".to_i(strict: false) # => 99

"0755".to_i                              # => 755
"0755".to_i(leading_zero_is_octal: true) # => 493
Source
to_i(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false, &)

Same as #to_i, but returns the block's value if there is not a valid number at the start of this string, or if the resulting integer doesn't fit an Int32.

"12345".to_i { 0 } # => 12345
"hello".to_i { 0 } # => 0
Source
to_i128(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : Int128

Same as #to_i but returns an Int128.

Source
to_i128(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false, &)

Same as #to_i but returns an Int128 or the block's value.

Source
to_i128?(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : Int128 | Nil

Same as #to_i but returns an Int128 or nil.

Source
to_i16(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : Int16

Same as #to_i but returns an Int16.

Source
to_i16(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false, &)

Same as #to_i but returns an Int16 or the block's value.

Source
to_i16?(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : Int16 | Nil

Same as #to_i but returns an Int16 or nil.

Source
to_i32(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : Int32

Same as #to_i.

Source
to_i32(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false, &)

Same as #to_i.

Source
to_i32?(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : Int32 | Nil

Same as #to_i.

Source
to_i64(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : Int64

Same as #to_i but returns an Int64.

Source
to_i64(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false, &)

Same as #to_i but returns an Int64 or the block's value.

Source
to_i64?(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : Int64 | Nil

Same as #to_i but returns an Int64 or nil.

Source
to_i8(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : Int8

Same as #to_i but returns an Int8.

Source
to_i8(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false, &)

Same as #to_i but returns an Int8 or the block's value.

Source
to_i8?(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : Int8 | Nil

Same as #to_i but returns an Int8 or nil.

Source
to_i?(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false)

Same as #to_i, but returns nil if there is not a valid number at the start of this string, or if the resulting integer doesn't fit an Int32.

"12345".to_i?             # => 12345
"99 red balloons".to_i?   # => nil
"0a".to_i?(strict: false) # => 0
"hello".to_i?             # => nil
Source
to_json(json : JSON::Builder) : Nil
Source
to_json_object_key
Source
to_s(io : IO) : Nil

Appends self to io.

Source
to_s

Returns self.

Source
to_slice

Returns the underlying bytes of this String.

The returned slice is read-only.

May contain invalid UTF-8 byte sequences; #scrub may be used to first obtain a String that is guaranteed to be valid UTF-8.

Source
to_u128(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : UInt128

Same as #to_i but returns an UInt128.

Source
to_u128(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false, &)

Same as #to_i but returns an UInt128 or the block's value.

Source
to_u128?(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : UInt128 | Nil

Same as #to_i but returns an UInt128 or nil.

Source
to_u16(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : UInt16

Same as #to_i but returns an UInt16.

Source
to_u16(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false, &)

Same as #to_i but returns an UInt16 or the block's value.

Source
to_u16?(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : UInt16 | Nil

Same as #to_i but returns an UInt16 or nil.

Source
to_u32(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : UInt32

Same as #to_i but returns an UInt32.

Source
to_u32(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false, &)

Same as #to_i but returns an UInt32 or the block's value.

Source
to_u32?(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : UInt32 | Nil

Same as #to_i but returns an UInt32 or nil.

Source
to_u64(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : UInt64

Same as #to_i but returns an UInt64.

Source
to_u64(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false, &)

Same as #to_i but returns an UInt64 or the block's value.

Source
to_u64?(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : UInt64 | Nil

Same as #to_i but returns an UInt64 or nil.

Source
to_u8(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : UInt8

Same as #to_i but returns an UInt8.

Source
to_u8(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false, &)

Same as #to_i but returns an UInt8 or the block's value.

Source
to_u8?(base : Int = 10, whitespace : Bool = true, underscore : Bool = false, prefix : Bool = false, strict : Bool = true, leading_zero_is_octal : Bool = false) : UInt8 | Nil

Same as #to_i but returns an UInt8 or nil.

Source
to_unsafe

Returns a pointer to the underlying bytes of this String.

May contain invalid UTF-8 byte sequences; #scrub may be used to first obtain a String that is guaranteed to be valid UTF-8.

The byte sequence at the pointer is always null-terminated (string.to_unsafe[string.bytesize] == 0u8), so it can be passed to C APIs that expects a NUL-terminated string. The string itself may also contain \0 bytes in the middle; the terminator is not a reliable end-of-string marker for strings that may embed '\0' bytes (see #check_no_null_byte for testing that).

Source
to_utf16

Returns the UTF-16 encoding of the given string.

Invalid chars (in the range U+D800..U+DFFF) are encoded with the unicode replacement char value 0xfffd.

The byte following the end of this slice (but not included in it) is defined to be zero. This allows passing the result of this function into C functions that expect a null-terminated UInt16*.

"hi 𐂥".to_utf16 # => Slice[104_u16, 105_u16, 32_u16, 55296_u16, 56485_u16]
Source
to_yaml(yaml : YAML::Nodes::Builder) : Nil
Source
tr(from : String, to : String) : String

Returns a new string _tr_anslating characters using from and to as a map. If to is shorter than from, the last character in to is used for the rest. If to is empty, this acts like String#delete.

"aabbcc".tr("abc", "xyz") # => "xxyyzz"
"aabbcc".tr("abc", "x")   # => "xxxxxx"
"aabbcc".tr("a", "xyz")   # => "xxbbcc"
Source
underscore(options : Unicode::CaseOptions = :none) : String

Converts camelcase boundaries to underscores.

"DoesWhatItSaysOnTheTin".underscore                         # => "does_what_it_says_on_the_tin"
"PartyInTheUSA".underscore                                  # => "party_in_the_usa"
"HTTP_CLIENT".underscore                                    # => "http_client"
"3.14IsPi".underscore                                       # => "3.14_is_pi"
"InterestingImage".underscore(Unicode::CaseOptions::Turkic) # => "ınteresting_ımage"
Source
underscore(io : IO, options : Unicode::CaseOptions = :none) : Nil

Writes an underscored version of self to the given io.

io = IO::Memory.new
"DoesWhatItSaysOnTheTin".underscore io
io.to_s # => "does_what_it_says_on_the_tin"
Source
unicode_normalize(form : Unicode::NormalizationForm = :nfc) : String

Returns the result of normalizing this String according to the given Unicode normalization form.

str = "\u{1E9B}\u{0323}"                # => "ẛ̣"
str.unicode_normalize.codepoints        # => [0x1E9B, 0x0323]
str.unicode_normalize(:nfd).codepoints  # => [0x017F, 0x0323, 0x0307]
str.unicode_normalize(:nfkc).codepoints # => [0x1E69]
str.unicode_normalize(:nfkd).codepoints # => [0x0073, 0x0323, 0x0307]
Source
unicode_normalize(io : IO, form : Unicode::NormalizationForm = :nfc) : Nil

Normalizes this String according to the given Unicode normalization form and writes the result to the given io.

Source
unicode_normalized?(form : Unicode::NormalizationForm = :nfc) : Bool

Returns whether this String is in the given Unicode normalization form.

foo = "\u{00E0}"              # => "à"
foo.unicode_normalized?       # => true
foo.unicode_normalized?(:nfd) # => false

bar = "\u{0061}\u{0300}"      # => "à"
bar.unicode_normalized?       # => false
bar.unicode_normalized?(:nfd) # => true
Source
unsafe_byte_at(index : Int) : UInt8

Returns the byte at the given index without bounds checking.

Source
unsafe_byte_slice(byte_offset, count) : Slice

Returns count of underlying bytes of this String starting at given byte_offset.

The returned slice is read-only.

Source
unsafe_byte_slice(byte_offset) : Slice

Returns the underlying bytes of this String starting at given byte_offset.

The returned slice is read-only.

Source
upcase(options : Unicode::CaseOptions = :none) : String

Returns a new String with each lowercase letter replaced with its uppercase counterpart.

"hEllO".upcase # => "HELLO"
Source
upcase(io : IO, options : Unicode::CaseOptions = :none) : Nil

Writes a upcased version of self to the given io.

io = IO::Memory.new
"hEllO".upcase io
io.to_s # => "HELLO"
Source
valid_encoding?

Returns true if this String is encoded correctly according to the UTF-8 encoding.

Source

Nested types