Spec-Zone.ru › Ruby 3.2

класс String

Родитель:
Объект
Включенные модули:
Comparable

Объект String имеет произвольную последовательность байтов, обычно представляющую текст или двоичные данные. Объект String можно создать, используя String::new или в качестве литералов.

String объекты отличаются от Symbol объектов тем, что Symbol объекты предназначены для использования в качестве идентификаторов, а не текста или данных.

Вы можете явно создать объект String с помощью:

  • строкового литерала.

  • литерала heredoc.

Вы можете преобразовать некоторые объекты в строки с помощью:

  • Метода String.

Некоторые методы String изменяют self. Обычно метод, имя которого заканчивается на !, изменяет self и возвращает self; часто аналогичный метод (без !) возвращает новую строку.

В общем случае, если существуют как bang, так и не-bang версии метода, bang! мутирует, а не-bang! нет. Однако метод без bang также может мутировать, например, String#replace.

Методы подстановки

Эти методы выполняют подстановки:

  • String#sub: Одна подстановка (или нет); возвращает новую строку.

  • String#sub!: Одна подстановка (или нет); возвращает self.

  • String#gsub: Ноль или более подстановок; возвращает новую строку.

  • String#gsub!: Ноль или более подстановок; возвращает self.

Каждый из этих методов принимает:

  • Первый аргумент, pattern (строка или регулярное выражение), который определяет подстроку(и) для замены.

  • Любой из этих вариантов:

    • Второй аргумент, replacement (строка или хэш), который определяет заменяющую строку.

    • Блок, который определит заменяющую строку.

Примеры в этом разделе в основном используют методы String#sub и String#gsub; описанные принципы применимы ко всем четырём методам подстановки.

Аргумент pattern

Аргумент pattern обычно представляет собой регулярное выражение:

s = 'hello'
s.sub(/[aeiou]/, '*')# => "h*llo"
s.gsub(/[aeiou]/, '*') # => "h*ll*"
s.gsub(/[aeiou]/, '')# => "hll"
s.sub(/ell/, 'al')   # => "halo"
s.gsub(/xyzzy/, '*') # => "hello"
'THX1138'.gsub(/\d+/, '00') # => "THX00"

Когда pattern является строкой, все её символы обрабатываются как обычные символы (а не как специальные символы регулярных выражений):

'THX1138'.gsub('\d+', '00') # => "THX1138"

Строка replacement

Если replacement является строкой, эта строка определит заменяющую строку, которая должна быть подставлена вместо совпавшего текста.

В каждом из приведённых выше примеров в качестве заменяющей строки используется простая строка.

Строка replacement может содержать обратные ссылки на захват подвыражений шаблона:

  • \n (n — целое неотрицательное число) относится к $n.

  • \k<name> относится к именованному захвату name.

Подробности см. в regexp.rdoc.

Обратите внимание, что в строке replacement, сочетание символов, например, $&, рассматривается как обычный текст, а не как специальная переменная сопоставления. Однако вы можете сослаться на некоторые специальные переменные сопоставления, используя эти сочетания:

  • \& и \0 соответствуют $&, содержащему весь совпавший текст.

  • \' соответствует $', содержащему строку после совпадения.

  • \` соответствует $`, содержащему строку перед совпадением.

  • + соответствует $+, содержащему последнюю группу захвата.

Подробности см. в regexp.rdoc.

Обратите внимание, что \\ интерпретируется как экранирование, т.е. одиночный обратный слэш.

Обратите также внимание, что строковый литерал потребляет обратные слэши. См. Строковые литералы для получения подробной информации о строковых литералах.

Обратная ссылка обычно предваряется дополнительным обратным слэшем. Например, если вы хотите записать обратную ссылку \& в replacement со строковым литералом с двойными кавычками, вам нужно написать "..\\&..".

Если вы хотите написать строку без обратной ссылки \& в replacement, вам сначала нужно экранировать обратный слэш, чтобы предотвратить интерпретацию этого метода как обратной ссылки, а затем нужно экранировать обратные слэши, чтобы предотвратить потребление их строковым литералом: "..\\\\&..".

Вы можете использовать форму с блоком, чтобы избежать большого количества обратных слэшей.

Хэш replacement

Если аргумент replacement является хэшем, и pattern соответствует одному из его ключей, заменяющая строка — это значение для этого ключа:

h = {'foo' => 'bar', 'baz' => 'bat'}
'food'.sub('foo', h) # => "bard"

Обратите внимание, что символ ключа не соответствует:

h = {foo: 'bar', baz: 'bat'}
'food'.sub('foo', h) # => "d"

Блок

В форме с блоком текущая строка совпадения передаётся в блок; возвращаемое значение блока становится заменяющей строкой:

 s = '@'
'1234'.gsub(/\d/) {|match| s.succ! } # => "ABCD"

Специальные переменные сопоставления, такие как $1, $2, $`, $&, и $' устанавливаются соответствующим образом.

Пробелы в строках

В классе String пробел определяется как непрерывная последовательность символов, состоящая из любой комбинации следующего:

  • NL (нуль): "\x00", "\u0000".

  • HT (горизонтальная табуляция): "\x09", "\t".

  • LF (перевод строки): "\x0a", "\n".

  • VT (вертикальная табуляция): "\x0b", "\v".

  • FF (форма подачи): "\x0c", "\f".

  • CR (возврат каретки): "\x0d", "\r".

  • SP (пробел): "\x20", " ".

Пробелы важны для этих методов:

  • lstrip, lstrip!: удаление начальных пробелов.

  • rstrip, rstrip!: удаление конечных пробелов.

  • strip, strip!: удаление начальных и конечных пробелов.

Срезы строк

Срез строки — это подстрока, выбранная по определённым критериям.

Эти методы экземпляров используют срезы:

  • String#[] (также алиас String#slice) возвращает копию среза из self.

  • String#[]= возвращает копию self со срезом, заменённым.

  • String#slice! возвращает self со срезом, удалённым.

Каждый из вышеперечисленных методов принимает аргументы, определяющие срез для копирования или замены.

Аргументы имеют несколько форм. Для строки string, формы являются:

  • string[index].

  • string[start, length].

  • string[range].

  • string[regexp, capture = 0].

  • string[substring].

string[index]

Когда целочисленный аргумент index имеет неотрицательное значение, срез представляет собой подстроку длиной 1 символ, найденную в self по смещению символа index:

'bar'[0]       # => "b"
'bar'[2]       # => "r"
'bar'[20]      # => nil
'тест'[2]      # => "с"
'こんにちは'[4]  # => "は"

Когда целочисленный аргумент index имеет отрицательное значение, срез начинается со смещения, полученного путём отсчёта назад от конца self:

'bar'[-3]         # => "b"
'bar'[-1]         # => "r"
'bar'[-20]        # => nil

string[start, length]

Когда целочисленные аргументы start и length имеют неотрицательные значения, срез начинается со смещения символа start, если оно существует, и продолжается в течение length символов, если они доступны:

'foo'[0, 2]       # => "fo"
'тест'[1, 2]      # => "ес"
'こんにちは'[2, 2]  # => "にち"
# Zero length.
'foo'[2, 0]       # => ""
# Length not entirely available.
'foo'[1, 200]     # => "oo"
# Start out of range.
'foo'[4, 2]      # => nil

Особый случай: если start равно длине self, срез — это новая пустая строка:

'foo'[3, 2]   # => ""
'foo'[3, 200] # => ""

Когда start отрицательное, а length неотрицательное, начало среза определяется путём отсчёта назад от конца self, а срез продолжается в течение length символов, если они доступны:

'foo'[-2, 2]    # => "oo"
'foo'[-2, 200]  # => "oo"
# Start out of range.
'foo'[-4, 2]     # => nil

Когда length отрицательное, среза нет:

'foo'[1, -1]  # => nil
'foo'[-2, -1] # => nil

string[range]

Когда аргумент Range range задан, создаёт подстроку string, используя индексы в range. Срез затем определяется как описано выше:

'foo'[0..1]    # => "fo"
'foo'[0, 2]    # => "fo"

'foo'[2...2]   # => ""
'foo'[2, 0]    # => ""

'foo'[1..200]  # => "oo"
'foo'[1, 200]  # => "oo"

'foo'[4..5]    # => nil
'foo'[4, 2]    # => nil

'foo'[-4..-3]  # => nil
'foo'[-4, 2]   # => nil

'foo'[3..4]    # => ""
'foo'[3, 2]    # => ""

'foo'[-2..-1]  # => "oo"
'foo'[-2, 2]   # => "oo"

'foo'[-2..197] # => "oo"
'foo'[-2, 200] # => "oo"

string[regexp, capture = 0]

Когда аргумент Regexp regexp задан, и аргумент capture равен 0, срез — это первая совпавшая подстрока, найденная в self:

'foo'[/o/] # => "o"
'foo'[/x/] # => nil
s = 'hello there'
s[/[aeiou](.)\1/] # => "ell"
s[/[aeiou](.)\1/, 0] # => "ell"

Если аргумент capture задан и не равен 0, он должен быть либо индексом группы захвата (целое число), либо именем группы захвата (строка или символ); срез — это указанная группа захвата (см. Захват в Regexp):

s = 'hello there'
s[/[aeiou](.)\1/, 1] # => "l"
s[/(?<vowel>[aeiou])(?<non_vowel>[^aeiou])/, "non_vowel"] # => "l"
s[/(?<vowel>[aeiou])(?<non_vowel>[^aeiou])/, :vowel] # => "e"

Если задан неверный индекс группы захвата, среза нет. Если задано неверное имя группы захвата, поднимается IndexError.

string[substring]

Если задан единственный аргумент String substring , возвращает подстроку, начиная с self, если она найдена, иначе возвращается nil:

'foo'['oo'] # => "oo"
'foo'['xx'] # => nil

Что здесь

Сначала, что где-то ещё. Класс String:

  • Наследуется от класса Object.

  • Включает модуль Comparable.

END_OF_DOCUMENT_MARKER

Здесь класс String предоставляет методы, полезные для:

  • Создание строки

  • Замороженные/размороженные строки

  • Запросы

  • Сравнение

  • Изменение строки

  • Преобразование в новую строку

  • Преобразование в не-строку

  • Итерация

Методы создания строки

  • ::new: Возвращает новую строку.

  • ::try_convert: Возвращает новую строку, созданную из заданного объекта.

Методы для замороженной/размороженной String

  • +@: Возвращает строку, которая не заморожена: self, если не заморожена; self.dup в противном случае.

  • -@: Возвращает замороженную строку: self, если уже заморожена; self.freeze в противном случае.

  • freeze: Замораживает self, если она еще не заморожена; возвращает self.

Методы запроса

Счёт

  • length, size: Возвращает количество символов (а не байтов).

  • empty?: Возвращает true если self.length равно нулю; false в противном случае.

  • bytesize: Возвращает количество байтов.

  • count: Возвращает количество подстрок, совпадающих с заданными строками.

Подстроки

  • =~: Возвращает индекс первой подстроки, которая соответствует заданному Regexp или другому объекту; возвращает nil если совпадение не найдено.

  • index: Возвращает индекс первого вхождения заданной подстроки; возвращает nil если не найдено.

  • rindex: Возвращает индекс последнего вхождения заданной подстроки; возвращает nil если не найдено.

  • include?: Возвращает true если строка содержит заданную подстроку; false в противном случае.

  • match: Возвращает объект MatchData, если строка соответствует заданному Regexp; nil в противном случае.

  • match?: Возвращает true если строка соответствует заданному Regexp; false в противном случае.

  • start_with?: Возвращает true если строка начинается с любой из заданных подстрок.

  • end_with?: Возвращает true если строка заканчивается любой из заданных подстрок.

Кодировки

  • encoding: Возвращает объект Encoding, который представляет кодировку строки.

  • unicode_normalized?: Возвращает true если строка находится в нормализованной форме Юникода; false в противном случае.

  • valid_encoding?: Возвращает true если строка содержит только символы, допустимые для ее кодировки.

  • ascii_only?: Возвращает true если строка содержит только символы ASCII; false в противном случае.

Прочее

  • sum: Возвращает базовую контрольную сумму для строки: сумму каждого байта.

  • hash: Возвращает целочисленный код хэша.

Методы сравнения

  • ==, ===: Возвращает true если заданная строка имеет то же содержимое, что и self.

  • eql?: Возвращает true если содержимое совпадает с заданной другой строкой.

  • <=>: Возвращает -1, 0 или 1, в зависимости от того, меньше ли заданная строка, равна ли она или больше, чем self.

  • casecmp: Игнорируя регистр, возвращает -1, 0 или 1, в зависимости от того, меньше ли заданная строка, равна ли она или больше, чем self.

  • casecmp?: Возвращает true если строка равна заданной строке после сгибания регистра Юникода; false в противном случае.

Методы изменения строки

Каждый из этих методов изменяет self.

Вставка

  • insert: Возвращает self со вставленной заданной строкой в заданном смещении.

  • <<: Возвращает self, конкатенированную с заданной строкой или целым числом.

Замена

  • sub!: Заменяет первую подстроку, соответствующую заданному шаблону, заданной строкой замены; возвращает self если изменения произошли, nil в противном случае.

  • gsub!: Заменяет каждую подстроку, соответствующую заданному шаблону, заданной строкой замены; возвращает self если изменения произошли, nil в противном случае.

  • succ!, next!: Возвращает self модифицированную, чтобы стать ее собственным преемником.

  • replace: Возвращает self с полностью заменённым содержимым заданной строкой.

  • reverse!: Возвращает self с переставленными символами в обратном порядке.

  • setbyte: Устанавливает байт в заданном смещении до заданного значения; возвращает аргумент.

  • tr!: Заменяет указанные символы в self указанными символами замены; возвращает self если изменения произошли, nil в противном случае.

  • tr_s!: Заменяет указанные символы в self указанными символами замены, удаляя дубликаты из подстрок, которые были изменены; возвращает self если изменения произошли, nil в противном случае.

Регистр

  • capitalize!: Преобразует начальный символ в верхний регистр, а все остальные - в нижний регистр; возвращает self если изменения произошли, nil в противном случае.

  • downcase!: Преобразует все символы в нижний регистр; возвращает self если изменения произошли, nil в противном случае.

  • upcase!: Преобразует все символы в верхний регистр; возвращает self если изменения произошли, nil в противном случае.

  • swapcase!: Преобразует каждый символ в нижнем регистре в верхний, и каждый символ в верхнем регистре в нижний; возвращает self если изменения произошли, nil в противном случае.

Кодировка

  • encode!: Возвращает self со всеми символами, транскодированными из одной заданной кодировки в другую.

  • unicode_normalize!: Нормализует Юникод self; возвращает self.

  • scrub!: Заменяет каждый недопустимый байт заданным символом; возвращает self.

  • force_encoding: Изменяет кодировку на заданную кодировку; возвращает self.

Удаление

  • clear: Удаляет все содержимое, так что self становится пустым; возвращает self.

  • slice!, []=: Удаляет подстроку, определяемую заданным индексом, началом/длиной, диапазоном, регулярным выражением или подстрокой.

  • squeeze!: Удаляет последовательные дублирующие символы; возвращает self.

  • delete!: Удаляет символы, определяемые пересечением подстрочных аргументов.

  • lstrip!: Удаляет начальные пробелы; возвращает self при изменениях, nil в противном случае.

  • rstrip!: Удаляет конечные пробелы; возвращает self при изменениях, nil в противном случае.

  • strip!: Удаляет начальные и конечные пробелы; возвращает self при изменениях, nil в противном случае.

  • chomp!: Удаляет конечный разделитель записей, если он найден; возвращает self при изменениях, nil в противном случае.

  • chop!: Удаляет конечные символы новой строки, если они найдены; в противном случае удаляет последний символ; возвращает self при изменениях, nil в противном случае.

Методы для преобразования в новую строку

Каждый из этих методов возвращает новую строку, основанную на self, часто просто изменённую копию self.

Расширение

  • *: Возвращает конкатенацию нескольких копий self,

  • +: Возвращает конкатенацию self и заданной другой строки.

  • center: Возвращает копию self, центрированную между подстроками заполнения.

  • concat: Возвращает конкатенацию self с заданными другими строками.

  • prepend: Возвращает конкатенацию заданной другой строки с self.

  • ljust: Возвращает копию self заданной длины, справа дополненную заданной другой строкой.

  • rjust: Возвращает копию self заданной длины, слева дополненную заданной другой строкой.

Кодировка

  • b: Возвращает копию self с кодировкой ASCII-8BIT.

  • scrub: Возвращает копию self с каждым недействительным байтом, заменённым заданным символом.

  • unicode_normalize: Возвращает копию self с каждым символом, унифицированным по Unicode.

  • encode: Возвращает копию self со всеми символами, преобразованными из одной заданной кодировки в другую.

Замена

  • dump: Возвращает копию self со всеми непечатаемыми символами, заменёнными на обозначение xHH, и всеми специальными символами, экранированными.

  • undump: Возвращает копию self со всеми обозначениями \xNN заменёнными на обозначения \uNNNN и всеми экранированными символами, деэкранированными.

  • sub: Возвращает копию self с первой подстрокой, соответствующей заданному шаблону, заменённой заданной строкой замены;.

  • gsub: Возвращает копию self с каждой подстрокой, соответствующей заданному шаблону, заменённой заданной строкой замены.

  • succ, next: Возвращает строку, являющуюся преемницей self.

  • reverse: Возвращает копию self с символами в обратном порядке.

  • tr: Возвращает копию self с указанными символами, заменёнными указанными символами замены.

  • tr_s: Возвращает копию self с указанными символами, заменёнными указанными символами замены, удаляя дубликаты из подстрок, которые были изменены.

  • %: Возвращает строку, полученную путём форматирования данного объекта в self

Регистр

  • capitalize: Возвращает копию self с первым символом в верхнем регистре и всеми другими символами в нижнем регистре.

  • downcase: Возвращает копию self со всеми символами в нижнем регистре.

  • upcase: Возвращает копию self со всеми символами в верхнем регистре.

  • swapcase: Возвращает копию self со всеми символами в верхнем регистре, переведёнными в нижний регистр, и всеми символами в нижнем регистре, переведёнными в верхний регистр.

Удаление

  • delete: Возвращает копию self с удалёнными символами

  • delete_prefix: Возвращает копию self с удалённым префиксом.

  • delete_suffix: Возвращает копию self с удалённым суффиксом.

  • lstrip: Возвращает копию self с удалёнными начальными пробелами.

  • rstrip: Возвращает копию self с удалёнными конечными пробелами.

  • strip: Возвращает копию self с удалёнными начальными и конечными пробелами.

  • chomp: Возвращает копию self с удалённым конечным разделителем записей, если он найден.

  • chop: Возвращает копию self с удалёнными конечными символами новой строки или последним символом.

  • squeeze: Возвращает копию self с удалёнными последовательными дублирующими символами.

  • [], slice: Возвращает подстроку, определяемую заданным индексом, началом/длиной или диапазоном, или строкой.

  • byteslice: Возвращает подстроку, определяемую заданным индексом, началом/длиной или диапазоном.

  • chr: Возвращает первый символ.

Дублирование

  • to_s, $to_str: Если self является подклассом String, возвращает self скопированным в String; в противном случае возвращает self.

Методы для преобразования в не-строку

Каждый из этих методов преобразует содержимое self в не-строку.

Символы, байты и кластеры

  • bytes: Возвращает массив байтов в self.

  • chars: Возвращает массив символов в self.

  • codepoints: Возвращает массив целочисленных порядковых номеров в self.

  • getbyte: Возвращает целочисленный байт, определённый заданным индексом.

  • grapheme_clusters: Возвращает массив кластеров графем в self.

Разделение

  • lines: Возвращает массив строк в self, как определено заданным разделителем записей.

  • partition: Возвращает массив из 3 элементов, определяемый первой подстрокой, которая соответствует заданной подстроке или регулярному выражению,

  • rpartition: Возвращает массив из 3 элементов, определяемый последней подстрокой, которая соответствует заданной подстроке или регулярному выражению,

  • split: Возвращает массив подстрок, определяемых заданным разделителем – регулярным выражением или строкой – или, если задан блок, передаёт эти подстроки в блок.

Сопоставление

  • scan: Возвращает массив подстрок, соответствующих заданному регулярному выражению или строке, или, если задан блок, передаёт каждую соответствующую подстроку в блок.

  • unpack: Возвращает массив подстрок, извлечённых из self в соответствии с заданным форматом.

  • unpack1: Возвращает первую подстроку, извлечённую из self в соответствии с заданным форматом.

Числа

  • hex: Возвращает целое значение ведущих символов, интерпретированных как шестнадцатеричные цифры.

  • oct: Возвращает целое значение ведущих символов, интерпретированных как восьмеричные цифры.

  • ord: Возвращает целочисленный порядковый номер первого символа в self.

  • to_i: Возвращает целое значение ведущих символов, интерпретированных как целое число.

  • to_f: Возвращает значение с плавающей точкой ведущих символов, интерпретированных как число с плавающей точкой.

Строки и Символы

  • inspect: Возвращает копию self, заключённую в двойные кавычки, со специальными символами, экранированными.

  • to_sym, intern: Возвращает символ, соответствующий self.

Методы для итерации

  • each_byte: Вызывает заданный блок для каждого последующего байта в self.

  • each_char: Вызывает заданный блок для каждого последующего символа в self.

  • each_codepoint: Вызывает заданный блок для каждого последующего целого кодового пункта в self.

  • each_grapheme_cluster: Вызывает заданный блок для каждого последующего графемного кластера в self.

  • each_line: Вызывает заданный блок для каждой последующей строки в self, как определено заданным разделителем записей.

  • upto: Вызывает заданный блок для каждого значения строки, возвращаемого последовательными вызовами succ.

Методы класса

new(string = '', **opts) → new_string Показать исходный код
static VALUE
rb_str_init(int argc, VALUE *argv, VALUE str)
{
    static ID keyword_ids[2];
    VALUE orig, opt, venc, vcapa;
    VALUE kwargs[2];
    rb_encoding *enc = 0;
    int n;

    if (!keyword_ids[0]) {
        keyword_ids[0] = rb_id_encoding();
        CONST_ID(keyword_ids[1], "capacity");
    }

    n = rb_scan_args(argc, argv, "01:", &orig, &opt);
    if (!NIL_P(opt)) {
        rb_get_kwargs(opt, keyword_ids, 0, 2, kwargs);
        venc = kwargs[0];
        vcapa = kwargs[1];
        if (!UNDEF_P(venc) && !NIL_P(venc)) {
            enc = rb_to_encoding(venc);
        }
        if (!UNDEF_P(vcapa) && !NIL_P(vcapa)) {
            long capa = NUM2LONG(vcapa);
            long len = 0;
            int termlen = enc ? rb_enc_mbminlen(enc) : 1;

            if (capa < STR_BUF_MIN_SIZE) {
                capa = STR_BUF_MIN_SIZE;
            }
            if (n == 1) {
                StringValue(orig);
                len = RSTRING_LEN(orig);
                if (capa < len) {
                    capa = len;
                }
                if (orig == str) n = 0;
            }
            str_modifiable(str);
            if (STR_EMBED_P(str)) { /* make noembed always */
                char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
#if USE_RVARGC
                assert(RSTRING(str)->as.embed.len + 1 <= str_embed_capa(str));
                memcpy(new_ptr, RSTRING(str)->as.embed.ary, RSTRING(str)->as.embed.len + 1);
#else
                memcpy(new_ptr, RSTRING(str)->as.embed.ary, RSTRING_EMBED_LEN_MAX + 1);
#endif
                RSTRING(str)->as.heap.ptr = new_ptr;
            }
            else if (FL_TEST(str, STR_SHARED|STR_NOFREE)) {
                const size_t size = (size_t)capa + termlen;
                const char *const old_ptr = RSTRING_PTR(str);
                const size_t osize = RSTRING(str)->as.heap.len + TERM_LEN(str);
                char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
                memcpy(new_ptr, old_ptr, osize < size ? osize : size);
                FL_UNSET_RAW(str, STR_SHARED|STR_NOFREE);
                RSTRING(str)->as.heap.ptr = new_ptr;
            }
            else if (STR_HEAP_SIZE(str) != (size_t)capa + termlen) {
                SIZED_REALLOC_N(RSTRING(str)->as.heap.ptr, char,
                        (size_t)capa + termlen, STR_HEAP_SIZE(str));
            }
            RSTRING(str)->as.heap.len = len;
            TERM_FILL(&RSTRING(str)->as.heap.ptr[len], termlen);
            if (n == 1) {
                memcpy(RSTRING(str)->as.heap.ptr, RSTRING_PTR(orig), len);
                rb_enc_cr_str_exact_copy(str, orig);
            }
            FL_SET(str, STR_NOEMBED);
            RSTRING(str)->as.heap.aux.capa = capa;
        }
        else if (n == 1) {
            rb_str_replace(str, orig);
        }
        if (enc) {
            rb_enc_associate(str, enc);
            ENC_CODERANGE_CLEAR(str);
        }
    }
    else if (n == 1) {
        rb_str_replace(str, orig);
    }
    return str;
}

Возвращает новую строку, являющуюся копией string.

Без аргументов возвращает пустую строку с кодировкой Encoding ASCII-8BIT:

s = String.new
s # => ""
s.encoding # => #<Encoding:ASCII-8BIT>

С необязательным аргументом string и без именованных аргументов, возвращает копию string с той же кодировкой:

String.new('foo')               # => "foo"
String.new('тест')              # => "тест"
String.new('こんにちは')          # => "こんにちは"

(В отличие от String.new, у литерала строки типа '' или литерала документа всегда используется кодировка скрипта.)

С необязательным именованным аргументом encoding, возвращает копию string с указанной кодировкой; encoding может быть объектом Encoding, именем кодировки или псевдонимом имени кодировки:

String.new('foo', encoding: Encoding::US_ASCII).encoding # => #<Encoding:US-ASCII>
String.new('foo', encoding: 'US-ASCII').encoding         # => #<Encoding:US-ASCII>
String.new('foo', encoding: 'ASCII').encoding            # => #<Encoding:US-ASCII>

Указанная кодировка необязательно должна быть валидной для содержимого строки, и эта валидность не проверяется:

s = String.new('こんにちは', encoding: 'ascii')
s.valid_encoding? # => false

Но указанный encoding проверяется:

String.new('foo', encoding: 'bar') # Raises ArgumentError.

С необязательным именованным аргументом capacity, возвращает копию string (или пустую строку, если string не указан); заданный capacity является лишь рекомендательным, и может или не может установить размер внутреннего буфера, что может повлиять на производительность:

String.new(capacity: 1)
String.new('foo', capacity: 4096)

Аргументы string, encoding, и capacity могут быть использованы вместе:

String.new('hello', encoding: 'UTF-8', capacity: 25)
try_convert(object) → object, new_string, or nil Показать исходный код
static VALUE
rb_str_s_try_convert(VALUE dummy, VALUE str)
{
    return rb_check_string_type(str);
}

Если object является объектом String, возвращает object.

В противном случае, если object отвечает на :to_str, вызывает object.to_str и возвращает результат.

Возвращает nil если object не отвечает на :to_str.

Вызывает исключение, если object.to_str не возвращает объект String.

Общедоступные методы экземпляров

строка % объект → новая_строка Показать исходный код
static VALUE
rb_str_format_m(VALUE str, VALUE arg)
{
    VALUE tmp = rb_check_array_type(arg);

    if (!NIL_P(tmp)) {
        return rb_str_format(RARRAY_LENINT(tmp), RARRAY_CONST_PTR(tmp), str);
    }
    return rb_str_format(1, &arg, str);
}

Возвращает результат форматирования object по спецификации формата self (см. Kernel#sprintf для подробностей о форматировании):

"%05d" % 123 # => "00123"

Если self содержит несколько подстановок, object должно быть массивом или хэшем, содержащим значения для подстановки:

"%-5s: %016x" % [ "ID", self.object_id ] # => "ID   : 00002b054ec93168"
"foo = %{foo}" % {foo: 'bar'} # => "foo = bar"
"foo = %{foo}, baz = %{baz}" % {foo: 'bar', baz: 'bat'} # => "foo = bar, baz = bat"
строка * целое число → новая_строка Показать исходный код
VALUE
rb_str_times(VALUE str, VALUE times)
{
    VALUE str2;
    long n, len;
    char *ptr2;
    int termlen;

    if (times == INT2FIX(1)) {
        return str_duplicate(rb_cString, str);
    }
    if (times == INT2FIX(0)) {
        str2 = str_alloc_embed(rb_cString, 0);
        rb_enc_copy(str2, str);
        return str2;
    }
    len = NUM2LONG(times);
    if (len < 0) {
        rb_raise(rb_eArgError, "negative argument");
    }
    if (RSTRING_LEN(str) == 1 && RSTRING_PTR(str)[0] == 0) {
        if (STR_EMBEDDABLE_P(len, 1)) {
            str2 = str_alloc_embed(rb_cString, len + 1);
            memset(RSTRING_PTR(str2), 0, len + 1);
        }
        else {
            str2 = str_alloc_heap(rb_cString);
            RSTRING(str2)->as.heap.aux.capa = len;
            RSTRING(str2)->as.heap.ptr = ZALLOC_N(char, (size_t)len + 1);
        }
        STR_SET_LEN(str2, len);
        rb_enc_copy(str2, str);
        return str2;
    }
    if (len && LONG_MAX/len <  RSTRING_LEN(str)) {
        rb_raise(rb_eArgError, "argument too big");
    }

    len *= RSTRING_LEN(str);
    termlen = TERM_LEN(str);
    str2 = str_new0(rb_cString, 0, len, termlen);
    ptr2 = RSTRING_PTR(str2);
    if (len) {
        n = RSTRING_LEN(str);
        memcpy(ptr2, RSTRING_PTR(str), n);
        while (n <= len/2) {
            memcpy(ptr2 + n, ptr2, n);
            n *= 2;
        }
        memcpy(ptr2 + n, ptr2, len-n);
    }
    STR_SET_LEN(str2, len);
    TERM_FILL(&ptr2[len], termlen);
    rb_enc_cr_str_copy_for_substr(str2, str);

    return str2;
}

Возвращает новую строку, содержащую integer копий self:

"Ho! " * 3 # => "Ho! Ho! Ho! "
"Ho! " * 0 # => ""
строка + другая_строка → новая_строка Показать исходный код
VALUE
rb_str_plus(VALUE str1, VALUE str2)
{
    VALUE str3;
    rb_encoding *enc;
    char *ptr1, *ptr2, *ptr3;
    long len1, len2;
    int termlen;

    StringValue(str2);
    enc = rb_enc_check_str(str1, str2);
    RSTRING_GETMEM(str1, ptr1, len1);
    RSTRING_GETMEM(str2, ptr2, len2);
    termlen = rb_enc_mbminlen(enc);
    if (len1 > LONG_MAX - len2) {
        rb_raise(rb_eArgError, "string size too big");
    }
    str3 = str_new0(rb_cString, 0, len1+len2, termlen);
    ptr3 = RSTRING_PTR(str3);
    memcpy(ptr3, ptr1, len1);
    memcpy(ptr3+len1, ptr2, len2);
    TERM_FILL(&ptr3[len1+len2], termlen);

    ENCODING_CODERANGE_SET(str3, rb_enc_to_index(enc),
                           ENC_CODERANGE_AND(ENC_CODERANGE(str1), ENC_CODERANGE(str2)));
    RB_GC_GUARD(str1);
    RB_GC_GUARD(str2);
    return str3;
}

Возвращает новую строку, содержащую other_string, конкатенированную с self:

"Hello from " + self.to_s # => "Hello from main"
+строка → новая_строка или self Показать исходный код
static VALUE
str_uplus(VALUE str)
{
    if (OBJ_FROZEN(str)) {
        return rb_str_dup(str);
    }
    else {
        return str;
    }
}

Возвращает self, если self не заморожена.

В противном случае возвращает self.dup, которая не заморожена.

-строка → замороженная_строка Показать исходный код
static VALUE
str_uminus(VALUE str)
{
    if (!BARE_STRING_P(str) && !rb_obj_frozen_p(str)) {
        str = rb_str_dup(str);
    }
    return rb_fstring(str);
}

Возвращает замороженную, возможно уже существующую копию строки.

Возвращаемая строка будет дедуплицирована, если у неё нет установленных экземпляра переменных и она не является подклассом String.

String#dedup является псевдонимом для String#-@.

Также псевдоним: dedup
строка << объект → строка Показать исходный код
VALUE
rb_str_concat(VALUE str1, VALUE str2)
{
    unsigned int code;
    rb_encoding *enc = STR_ENC_GET(str1);
    int encidx;

    if (RB_INTEGER_TYPE_P(str2)) {
        if (rb_num_to_uint(str2, &code) == 0) {
        }
        else if (FIXNUM_P(str2)) {
            rb_raise(rb_eRangeError, "%ld out of char range", FIX2LONG(str2));
        }
        else {
            rb_raise(rb_eRangeError, "bignum out of char range");
        }
    }
    else {
        return rb_str_append(str1, str2);
    }

    encidx = rb_ascii8bit_appendable_encoding_index(enc, code);
    if (encidx >= 0) {
        char buf[1];
        buf[0] = (char)code;
        rb_str_cat(str1, buf, 1);
        if (encidx != rb_enc_to_index(enc)) {
            rb_enc_associate_index(str1, encidx);
            ENC_CODERANGE_SET(str1, ENC_CODERANGE_VALID);
        }
    }
    else {
        long pos = RSTRING_LEN(str1);
        int cr = ENC_CODERANGE(str1);
        int len;
        char *buf;

        switch (len = rb_enc_codelen(code, enc)) {
          case ONIGERR_INVALID_CODE_POINT_VALUE:
            rb_raise(rb_eRangeError, "invalid codepoint 0x%X in %s", code, rb_enc_name(enc));
            break;
          case ONIGERR_TOO_BIG_WIDE_CHAR_VALUE:
          case 0:
            rb_raise(rb_eRangeError, "%u out of char range", code);
            break;
        }
        buf = ALLOCA_N(char, len + 1);
        rb_enc_mbcput(code, buf, enc);
        if (rb_enc_precise_mbclen(buf, buf + len + 1, enc) != len) {
            rb_raise(rb_eRangeError, "invalid codepoint 0x%X in %s", code, rb_enc_name(enc));
        }
        rb_str_resize(str1, pos+len);
        memcpy(RSTRING_PTR(str1) + pos, buf, len);
        if (cr == ENC_CODERANGE_7BIT && code > 127)
            cr = ENC_CODERANGE_VALID;
        ENC_CODERANGE_SET(str1, cr);
    }
    return str1;
}

Конкатенирует object со self и возвращает self:

s = 'foo'
s << 'bar' # => "foobar"
s          # => "foobar"

Если object является целым числом, значение рассматривается как код символа и преобразуется в символ перед конкатенацией:

s = 'foo'
s << 33 # => "foo!"

Связанно с: String#concat, который принимает несколько аргументов.

строка <=> другая_строка → -1, 0, 1 или nil Показать исходный код
static VALUE
rb_str_cmp_m(VALUE str1, VALUE str2)
{
    int result;
    VALUE s = rb_check_string_type(str2);
    if (NIL_P(s)) {
        return rb_invcmp(str1, str2);
    }
    result = rb_str_cmp(str1, s);
    return INT2FIX(result);
}

Сравнивает self и other_string, возвращая:

  • -1, если other_string больше.

  • 0, если оба значения равны.

  • 1, если other_string меньше.

  • nil, если оба значения несравнимы.

Примеры:

'foo' <=> 'foo' # => 0
'foo' <=> 'food' # => -1
'food' <=> 'foo' # => 1
'FOO' <=> 'foo' # => -1
'foo' <=> 'FOO' # => 1
'foo' <=> 1 # => nil
строка == объект → true или false Показать исходный код
VALUE
rb_str_equal(VALUE str1, VALUE str2)
{
    if (str1 == str2) return Qtrue;
    if (!RB_TYPE_P(str2, T_STRING)) {
        if (!rb_respond_to(str2, idTo_str)) {
            return Qfalse;
        }
        return rb_equal(str2, str1);
    }
    return rb_str_eql_internal(str1, str2);
}

Возвращает true если object имеет такую же длину и содержимое, как self; false в противном случае:

s = 'foo'
s == 'foo' # => true
s == 'food' # => false
s == 'FOO' # => false

Возвращает false если кодировки двух строк несовместимы:

"\u{e4 f6 fc}".encode("ISO-8859-1") == ("\u{c4 d6 dc}") # => false

Если object не является экземпляром String, но отвечает на to_str, тогда две строки сравниваются с помощью object.==.

Также псевдоним: ===
строка === объект → true или false

Возвращает true если object имеет такую же длину и содержимое, как self; false в противном случае:

s = 'foo'
s == 'foo' # => true
s == 'food' # => false
s == 'FOO' # => false

Возвращает false если кодировки двух строк несовместимы:

"\u{e4 f6 fc}".encode("ISO-8859-1") == ("\u{c4 d6 dc}") # => false

Если object не является экземпляром String, но отвечает на to_str, тогда две строки сравниваются с помощью object.==.

Псевдоним для: ==
строка =~ регулярное_выражение → целое число или nil Показать исходный код
строка =~ объект → целое число или nil
static VALUE
rb_str_match(VALUE x, VALUE y)
{
    switch (OBJ_BUILTIN_TYPE(y)) {
      case T_STRING:
        rb_raise(rb_eTypeError, "type mismatch: String given");

      case T_REGEXP:
        return rb_reg_match(y, x);

      default:
        return rb_funcall(y, idEqTilde, 1, x);
    }
}

Возвращает индекс первого подстроки, соответствующей заданному regexp, или nil если совпадение не найдено:

'foo' =~ /f/ # => 0
'foo' =~ /o/ # => 1
'foo' =~ /x/ # => nil

Примечание: также обновляет Специальные глобальные переменные по адресу Regexp.

Если заданное object не является регулярным выражением, возвращает значение, возвращаемое object =~ self.

Обратите внимание, что string =~ regexp отличается от regexp =~ string (см. Regexp#=~):

number= nil
"no. 9" =~ /(?<number>\d+)/
number # => nil (not assigned)
/(?<number>\d+)/ =~ "no. 9"
number #=> "9"
строка[индекс] → новая_строка или nil Показать исходный код
строка[начало, длина] → новая_строка или nil
строка[диапазон] → новая_строка или nil
строка[регулярное_выражение, захват = 0] → новая_строка или nil
строка[подстрока] → новая_строка или nil
static VALUE
rb_str_aref_m(int argc, VALUE *argv, VALUE str)
{
    if (argc == 2) {
        if (RB_TYPE_P(argv[0], T_REGEXP)) {
            return rb_str_subpat(str, argv[0], argv[1]);
        }
        else {
            long beg = NUM2LONG(argv[0]);
            long len = NUM2LONG(argv[1]);
            return rb_str_substr(str, beg, len);
        }
    }
    rb_check_arity(argc, 1, 2);
    return rb_str_aref(str, argv[0]);
}

Возвращает подстроку self, заданную аргументами. Примеры см. в разделе Слайсы строк.

Также псевдоним: slice
строка[индекс] = новая_строка Показать исходный код
строка[начало, длина] = новая_строка
строка[диапазон] = новая_строка
строка[регулярное_выражение, захват = 0] = новая_строка
строка[подстрока] = новая_строка
static VALUE
rb_str_aset_m(int argc, VALUE *argv, VALUE str)
{
    if (argc == 3) {
        if (RB_TYPE_P(argv[0], T_REGEXP)) {
            rb_str_subpat_set(str, argv[0], argv[1], argv[2]);
        }
        else {
            rb_str_splice(str, NUM2LONG(argv[0]), NUM2LONG(argv[1]), argv[2]);
        }
        return argv[2];
    }
    rb_check_arity(argc, 2, 3);
    return rb_str_aset(str, argv[0], argv[1]);
}

Заменяет все, некоторые или ни одной части содержимого self; возвращает new_string. См. Слайсы строк.

Несколько примеров:

s = 'foo'
s[2] = 'rtune'     # => "rtune"
s                  # => "fortune"
s[1, 5] = 'init'   # => "init"
s                  # => "finite"
s[3..4] = 'al'     # => "al"
s                  # => "finale"
s[/e$/] = 'ly'     # => "ly"
s                  # => "finally"
s['lly'] = 'ncial' # => "ncial"
s                  # => "financial"

String#slice является псевдонимом для String#[].

ascii_only? → true или false Показать исходный код
static VALUE
rb_str_is_ascii_only_p(VALUE str)
{
    int cr = rb_enc_str_coderange(str);

    return RBOOL(cr == ENC_CODERANGE_7BIT);
}

Возвращает true если self содержит только символы ASCII, false в противном случае:

'abc'.ascii_only?         # => true
"abc\u{6666}".ascii_only? # => false
b → строка Показать исходный код
static VALUE
rb_str_b(VALUE str)
{
    VALUE str2;
    if (FL_TEST(str, STR_NOEMBED)) {
        str2 = str_alloc_heap(rb_cString);
    }
    else {
        str2 = str_alloc_embed(rb_cString, RSTRING_EMBED_LEN(str) + TERM_LEN(str));
    }
    str_replace_shared_without_enc(str2, str);

    if (rb_enc_asciicompat(STR_ENC_GET(str))) {
        // BINARY strings can never be broken; they're either 7-bit ASCII or VALID.
        // If we know the receiver's code range then we know the result's code range.
        int cr = ENC_CODERANGE(str);
        switch (cr) {
          case ENC_CODERANGE_7BIT:
            ENC_CODERANGE_SET(str2, ENC_CODERANGE_7BIT);
            break;
          case ENC_CODERANGE_BROKEN:
          case ENC_CODERANGE_VALID:
            ENC_CODERANGE_SET(str2, ENC_CODERANGE_VALID);
            break;
          default:
            ENC_CODERANGE_CLEAR(str2);
            break;
        }
    }

    return str2;
}

Возвращает копию self с кодировкой ASCII-8BIT; лежащие в основе байты не изменяются:

s = "\x99"
s.encoding   # => #<Encoding:UTF-8>
t = s.b      # => "\x99"
t.encoding   # => #<Encoding:ASCII-8BIT>

s = "\u4095" # => "䂕"
s.encoding   # => #<Encoding:UTF-8>
s.bytes      # => [228, 130, 149]
t = s.b      # => "\xE4\x82\x95"
t.encoding   # => #<Encoding:ASCII-8BIT>
t.bytes      # => [228, 130, 149]
END_OF_DOCUMENT_MARKER
byteindex(substring, offset = 0) → целое число или nil Показать исходный код
byteindex(regexp, offset = 0) → целое число или nil
static VALUE
rb_str_byteindex_m(int argc, VALUE *argv, VALUE str)
{
    VALUE sub;
    VALUE initpos;
    long pos;

    if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) {
        pos = NUM2LONG(initpos);
    }
    else {
        pos = 0;
    }
    if (pos < 0) {
        pos += RSTRING_LEN(str);
        if (pos < 0) {
            if (RB_TYPE_P(sub, T_REGEXP)) {
                rb_backref_set(Qnil);
            }
            return Qnil;
        }
    }

    if (!str_check_byte_pos(str, pos)) {
        rb_raise(rb_eIndexError,
                 "offset %ld does not land on character boundary", pos);
    }

    if (RB_TYPE_P(sub, T_REGEXP)) {
        if (pos > RSTRING_LEN(str))
            return Qnil;
        if (rb_reg_search(sub, str, pos, 0) < 0) {
            return Qnil;
        }
        else {
            VALUE match = rb_backref_get();
            struct re_registers *regs = RMATCH_REGS(match);
            pos = BEG(0);
            return LONG2NUM(pos);
        }
    }
    else {
        StringValue(sub);
        pos = rb_strseq_index(str, sub, pos, 1);
    }

    if (pos == -1) return Qnil;
    return LONG2NUM(pos);
}

Возвращает целое число — индекс байта первого вхождения заданной substring, или nil если ничего не найдено:

'foo'.byteindex('f') # => 0
'foo'.byteindex('o') # => 1
'foo'.byteindex('oo') # => 1
'foo'.byteindex('ooo') # => nil

Возвращает целое число — индекс байта первого совпадения для заданного Regexp regexp, или nil если ничего не найдено:

'foo'.byteindex(/f/) # => 0
'foo'.byteindex(/o/) # => 1
'foo'.byteindex(/oo/) # => 1
'foo'.byteindex(/ooo/) # => nil

Целое число offset, если задано, определяет позицию в строке для начала поиска:

'foo'.byteindex('o', 1) # => 1
'foo'.byteindex('o', 2) # => 2
'foo'.byteindex('o', 3) # => nil

Если offset отрицательно, счёт идёт от конца self:

'foo'.byteindex('o', -1) # => 2
'foo'.byteindex('o', -2) # => 1
'foo'.byteindex('o', -3) # => 1
'foo'.byteindex('o', -4) # => nil

Если offset не попадает на границу символа (кодовой точки), IndexError будет возбуждено.

Связанные: String#index, String#byterindex.

byterindex(substring, offset = self.bytesize) → целое число или nil Показать исходный код
byterindex(regexp, offset = self.bytesize) → целое число или nil
static VALUE
rb_str_byterindex_m(int argc, VALUE *argv, VALUE str)
{
    VALUE sub;
    VALUE vpos;
    long pos, len = RSTRING_LEN(str);

    if (rb_scan_args(argc, argv, "11", &sub, &vpos) == 2) {
        pos = NUM2LONG(vpos);
        if (pos < 0) {
            pos += len;
            if (pos < 0) {
                if (RB_TYPE_P(sub, T_REGEXP)) {
                    rb_backref_set(Qnil);
                }
                return Qnil;
            }
        }
        if (pos > len) pos = len;
    }
    else {
        pos = len;
    }

    if (!str_check_byte_pos(str, pos)) {
        rb_raise(rb_eIndexError,
                 "offset %ld does not land on character boundary", pos);
    }

    if (RB_TYPE_P(sub, T_REGEXP)) {
        if (rb_reg_search(sub, str, pos, 1) >= 0) {
            VALUE match = rb_backref_get();
            struct re_registers *regs = RMATCH_REGS(match);
            pos = BEG(0);
            return LONG2NUM(pos);
        }
    }
    else {
        StringValue(sub);
        pos = rb_str_byterindex(str, sub, pos);
        if (pos >= 0) return LONG2NUM(pos);
    }
    return Qnil;
}

Возвращает целое число — индекс байта последнего вхождения заданной substring, или nil если ничего не найдено:

'foo'.byterindex('f') # => 0
'foo'.byterindex('o') # => 2
'foo'.byterindex('oo') # => 1
'foo'.byterindex('ooo') # => nil

Последнее вхождение означает, что поиск начинается с предположительно последней позиции, а не с последней из самых длинных совпадений.

'foo'.byterindex(/o+/) # => 2
$~ #=> #<MatchData "o">

Для получения последнего наиболее длинного совпадения необходимо комбинировать с отрицательным просмотром назад.

'foo'.byterindex(/(?<!o)o+/) # => 1
$~ #=> #<MatchData "oo">

Или String#byteindex с отрицательным просмотром вперёд.

'foo'.byteindex(/o+(?!.*o)/) # => 1
$~ #=> #<MatchData "oo">

Целое число offset, если задано и неотрицательно, задаёт максимальную стартовую позицию в строке по байтам.

string to _end_ the search:

 'foo'.byterindex('o', 0) # => nil
 'foo'.byterindex('o', 1) # => 1
 'foo'.byterindex('o', 2) # => 2
 'foo'.byterindex('o', 3) # => 2

Если offset является отрицательным целым числом, максимальная начальная позиция в строке для завершения поиска — сумма длины строки и offset:

'foo'.byterindex('o', -1) # => 2
'foo'.byterindex('o', -2) # => 1
'foo'.byterindex('o', -3) # => nil
'foo'.byterindex('o', -4) # => nil

Если offset не попадает на границу символа (кодовой точки), IndexError будет возбуждено.

Связанные: String#byteindex.

bytes → массив_байтов Показать исходный код
static VALUE
rb_str_bytes(VALUE str)
{
    VALUE ary = WANTARRAY("bytes", RSTRING_LEN(str));
    return rb_str_enumerate_bytes(str, ary);
}

Возвращает массив байтов в self:

'hello'.bytes # => [104, 101, 108, 108, 111]
'тест'.bytes  # => [209, 130, 208, 181, 209, 129, 209, 130]
'こんにちは'.bytes
# => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175]
bytesize → целое число Показать исходный код
static VALUE
rb_str_bytesize(VALUE str)
{
    return LONG2NUM(RSTRING_LEN(str));
}

Возвращает количество байтов (не символов) в self:

'foo'.bytesize        # => 3
'тест'.bytesize       # => 8
'こんにちは'.bytesize   # => 15

В отличие от String#length:

'foo'.length       # => 3
'тест'.length      # => 4
'こんにちは'.length  # => 5
byteslice(index, length = 1) → строка или nil
byteslice(range) → строка или nil
static VALUE
rb_str_byteslice(int argc, VALUE *argv, VALUE str)
{
    if (argc == 2) {
        long beg = NUM2LONG(argv[0]);
        long len = NUM2LONG(argv[1]);
        return str_byte_substr(str, beg, len, TRUE);
    }
    rb_check_arity(argc, 1, 2);
    return str_byte_aref(str, argv[0]);
}

Возвращает подстроку self, или nil если подстрока не может быть построена.

С целочисленными аргументами index и length , возвращает подстроку, начинающуюся с заданного index заданной length, если возможно, или nil если length отрицательно или index выходит за пределы self:

s = '0123456789' # => "0123456789"
s.byteslice(2)   # => "2"
s.byteslice(200) # => nil
s.byteslice(4, 3)  # => "456"
s.byteslice(4, 30) # => "456789"
s.byteslice(4, -1) # => nil
s.byteslice(40, 2) # => nil

В обоих случаях выше счёт идёт от конца self если index отрицательно:

s = '0123456789'   # => "0123456789"
s.byteslice(-4)    # => "6"
s.byteslice(-4, 3) # => "678"

С аргументом диапазона Range range возвращает byteslice(range.begin, range.size):

s = '0123456789'    # => "0123456789"
s.byteslice(4..6)   # => "456"
s.byteslice(-6..-4) # => "456"
s.byteslice(5..2)   # => "" # range.size is zero.
s.byteslice(40..42) # => nil

Во всех случаях возвращаемая строка имеет тот же кодирование, что и self:

s.encoding              # => #<Encoding:UTF-8>
s.byteslice(4).encoding # => #<Encoding:UTF-8>
bytesplice(index, length, str) → строка
bytesplice(range, str) → строка
static VALUE
rb_str_bytesplice(int argc, VALUE *argv, VALUE str)
{
    long beg, end, len, slen;
    VALUE val;
    rb_encoding *enc;
    int cr;

    rb_check_arity(argc, 2, 3);
    if (argc == 2) {
        if (!rb_range_beg_len(argv[0], &beg, &len, RSTRING_LEN(str), 2)) {
            rb_raise(rb_eTypeError, "wrong argument type %s (expected Range)",
                     rb_builtin_class_name(argv[0]));
        }
        val = argv[1];
    }
    else {
        beg = NUM2LONG(argv[0]);
        len = NUM2LONG(argv[1]);
        val = argv[2];
    }
    if (len < 0) rb_raise(rb_eIndexError, "negative length %ld", len);
    slen = RSTRING_LEN(str);
    if ((slen < beg) || ((beg < 0) && (beg + slen < 0))) {
        rb_raise(rb_eIndexError, "index %ld out of string", beg);
    }
    if (beg < 0) {
        beg += slen;
    }
    assert(beg >= 0);
    assert(beg <= slen);
    if (len > slen - beg) {
        len = slen - beg;
    }
    end = beg + len;
    if (!str_check_byte_pos(str, beg)) {
        rb_raise(rb_eIndexError,
                 "offset %ld does not land on character boundary", beg);
    }
    if (!str_check_byte_pos(str, end)) {
        rb_raise(rb_eIndexError,
                 "offset %ld does not land on character boundary", end);
    }
    StringValue(val);
    enc = rb_enc_check(str, val);
    str_modify_keep_cr(str);
    rb_str_splice_0(str, beg, len, val);
    rb_enc_associate(str, enc);
    cr = ENC_CODERANGE_AND(ENC_CODERANGE(str), ENC_CODERANGE(val));
    if (cr != ENC_CODERANGE_BROKEN)
        ENC_CODERANGE_SET(str, cr);
    return val;
}

Заменяет часть или всё содержимое self на str, и возвращает str. Часть строки, на которую влияет замена, определяется теми же критериями, что и String#byteslice, за исключением того, что length не может быть опущено. Если строка замены не имеет такой же длины, как текст, который она заменяет, строка будет соответствующим образом скорректирована. Форма, принимающая Integer, вызовет IndexError, если значение находится вне диапазона; форма с Range вызовет RangeError. Если начальная или конечная позиция не попадает на границу символа (кодовой точки), будет возбуждено исключение IndexError.

capitalize(*options) → строка Показать исходный код
static VALUE
rb_str_capitalize(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    OnigCaseFoldType flags = ONIGENC_CASE_UPCASE | ONIGENC_CASE_TITLECASE;
    VALUE ret;

    flags = check_case_options(argc, argv, flags);
    enc = str_true_enc(str);
    if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return str;
    if (flags&ONIGENC_CASE_ASCII_ONLY) {
        ret = rb_str_new(0, RSTRING_LEN(str));
        rb_str_ascii_casemap(str, ret, &flags, enc);
    }
    else {
        ret = rb_str_casemap(str, &flags, enc);
    }
    return ret;
}

Возвращает строку, содержащую символы из self; первый символ — заглавный, остальные — строчные:

s = 'hello World!' # => "hello World!"
s.capitalize       # => "Hello world!"

Регистр может быть изменён заданными options; см. Преобразование регистра.

Связанные: String#capitalize!.

capitalize!(*options) → self или nil Показать исходный код
static VALUE
rb_str_capitalize_bang(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    OnigCaseFoldType flags = ONIGENC_CASE_UPCASE | ONIGENC_CASE_TITLECASE;

    flags = check_case_options(argc, argv, flags);
    str_modify_keep_cr(str);
    enc = str_true_enc(str);
    if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return Qnil;
    if (flags&ONIGENC_CASE_ASCII_ONLY)
        rb_str_ascii_casemap(str, str, &flags, enc);
    else
        str_shared_replace(str, rb_str_casemap(str, &flags, enc));

    if (ONIGENC_CASE_MODIFIED&flags) return str;
    return Qnil;
}

Преобразует первый символ в self; преобразует остальные символы в строчные; возвращает self если изменения были внесены, nil в противном случае:

s = 'hello World!' # => "hello World!"
s.capitalize!      # => "Hello world!"
s                  # => "Hello world!"
s.capitalize!      # => nil

Регистр может быть изменён заданными options; см. Преобразование регистра.

Связанные: String#capitalize.

casecmp(other_string) → -1, 0, 1, или nil Показать исходный код
static VALUE
rb_str_casecmp(VALUE str1, VALUE str2)
{
    VALUE s = rb_check_string_type(str2);
    if (NIL_P(s)) {
        return Qnil;
    }
    return str_casecmp(str1, s);
}

Сравнивает self.downcase и other_string.downcase; возвращает:

  • -1 если other_string.downcase больше.

  • 0 если оба равны.

  • 1 если other_string.downcase меньше.

  • nil если два значения несравнимы.

Примеры:

'foo'.casecmp('foo') # => 0
'foo'.casecmp('food') # => -1
'food'.casecmp('foo') # => 1
'FOO'.casecmp('foo') # => 0
'foo'.casecmp('FOO') # => 0
'foo'.casecmp(1) # => nil

См. Преобразование регистра.

Связанные: String#casecmp?.

casecmp?(other_string) → true, false, или nil Показать исходный код
static VALUE
rb_str_casecmp_p(VALUE str1, VALUE str2)
{
    VALUE s = rb_check_string_type(str2);
    if (NIL_P(s)) {
        return Qnil;
    }
    return str_casecmp_p(str1, s);
}

Возвращает true если self и other_string равны после свёртки регистра Unicode, в противном случае false:

'foo'.casecmp?('foo') # => true
'foo'.casecmp?('food') # => false
'food'.casecmp?('foo') # => false
'FOO'.casecmp?('foo') # => true
'foo'.casecmp?('FOO') # => true

Возвращает nil если два значения несравнимы:

'foo'.casecmp?(1) # => nil

См. Преобразование регистра.

Связанные: String#casecmp.

center(size, pad_string = ' ') → new_string Показать исходный код
static VALUE
rb_str_center(int argc, VALUE *argv, VALUE str)
{
    return rb_str_justify(argc, argv, str, 'c');
}

Возвращает выровненную по центру копию self.

Если целое число size больше размера (в символах) self, возвращает новую строку длиной size, которая является копией self, выровненной по центру и дополненной по обеим сторонам pad_string:

'hello'.center(10)       # => "  hello   "
'  hello'.center(10)     # => "   hello  "
'hello'.center(10, 'ab') # => "abhelloaba"
'тест'.center(10)        # => "   тест   "
'こんにちは'.center(10)    # => "  こんにちは   "

Если size не больше размера self, возвращает копию self:

'hello'.center(5)  # => "hello"
'hello'.center(1)  # => "hello"

Связанные: String#ljust, String#rjust.

chars → array_of_characters Показать исходный код
static VALUE
rb_str_chars(VALUE str)
{
    VALUE ary = WANTARRAY("chars", rb_str_strlen(str));
    return rb_str_enumerate_chars(str, ary);
}

Возвращает массив символов в self;

'hello'.chars     # => ["h", "e", "l", "l", "o"]
'тест'.chars      # => ["т", "е", "с", "т"]
'こんにちは'.chars # => ["こ", "ん", "に", "ち", "は"]
chomp(line_sep = $/) → new_string Показать исходный код
static VALUE
rb_str_chomp(int argc, VALUE *argv, VALUE str)
{
    VALUE rs = chomp_rs(argc, argv);
    if (NIL_P(rs)) return str_duplicate(rb_cString, str);
    return rb_str_subseq(str, 0, chompped_length(str, rs));
}

Возвращает новую строку, скопированную из self, с возможным удалением конечных символов:

Когда line_sep равно "\n", удаляет один или два последних символа, если они являются "\r", "\n", или "\r\n" (но не "\n\r"):

$/                    # => "\n"
"abc\r".chomp         # => "abc"
"abc\n".chomp         # => "abc"
"abc\r\n".chomp       # => "abc"
"abc\n\r".chomp       # => "abc\n"
"тест\r\n".chomp      # => "тест"
"こんにちは\r\n".chomp  # => "こんにちは"

Когда line_sep равно '' (пустая строка), удаляет несколько конечных вхождений "\n" или "\r\n" (но не "\r" или "\n\r"):

"abc\n\n\n".chomp('')           # => "abc"
"abc\r\n\r\n\r\n".chomp('')     # => "abc"
"abc\n\n\r\n\r\n\n\n".chomp('') # => "abc"
"abc\n\r\n\r\n\r".chomp('')     # => "abc\n\r\n\r\n\r"
"abc\r\r\r".chomp('')           # => "abc\r\r\r"

Когда line_sep ни "\n", ни '', удаляет один конечный разделитель строки, если он есть:

'abcd'.chomp('d')  # => "abc"
'abcdd'.chomp('d') # => "abcd"
chomp!(line_sep = $/) → self or nil Показать исходный код
static VALUE
rb_str_chomp_bang(int argc, VALUE *argv, VALUE str)
{
    VALUE rs;
    str_modifiable(str);
    if (RSTRING_LEN(str) == 0) return Qnil;
    rs = chomp_rs(argc, argv);
    if (NIL_P(rs)) return Qnil;
    return rb_str_chomp_string(str, rs);
}

Подобно String#chomp, но изменяет self на месте; возвращает nil если изменения не было, self в противном случае.

chop → new_string Показать исходный код
static VALUE
rb_str_chop(VALUE str)
{
    return rb_str_subseq(str, 0, chopped_length(str));
}

Возвращает новую строку, скопированную из self, с возможным удалением конечных символов.

Удаляет "\r\n" если они являются последними двумя символами.

"abc\r\n".chop      # => "abc"
"тест\r\n".chop     # => "тест"
"こんにちは\r\n".chop # => "こんにちは"

В противном случае удаляет последний символ, если он существует.

'abcd'.chop     # => "abc"
'тест'.chop     # => "тес"
'こんにちは'.chop # => "こんにち"
''.chop         # => ""

Если вам нужно только удалить символ перевода строки в конце строки, String#chomp является лучшим вариантом.

chop! → self or nil Показать исходный код
static VALUE
rb_str_chop_bang(VALUE str)
{
    str_modify_keep_cr(str);
    if (RSTRING_LEN(str) > 0) {
        long len;
        len = chopped_length(str);
        STR_SET_LEN(str, len);
        TERM_FILL(&RSTRING_PTR(str)[len], TERM_LEN(str));
        if (ENC_CODERANGE(str) != ENC_CODERANGE_7BIT) {
            ENC_CODERANGE_CLEAR(str);
        }
        return str;
    }
    return Qnil;
}

Подобно String#chop, но изменяет self на месте; возвращает nil если self пуста, self в противном случае.

Связанно с: String#chomp!.

chr → string Показать исходный код
static VALUE
rb_str_chr(VALUE str)
{
    return rb_str_substr(str, 0, 1);
}

Возвращает строку, содержащую первый символ self:

s = 'foo' # => "foo"
s.chr     # => "f"
clear → self Показать исходный код
static VALUE
rb_str_clear(VALUE str)
{
    str_discard(str);
    STR_SET_EMBED(str);
    STR_SET_EMBED_LEN(str, 0);
    RSTRING_PTR(str)[0] = 0;
    if (rb_enc_asciicompat(STR_ENC_GET(str)))
        ENC_CODERANGE_SET(str, ENC_CODERANGE_7BIT);
    else
        ENC_CODERANGE_SET(str, ENC_CODERANGE_VALID);
    return str;
}

Удаляет содержимое self:

s = 'foo' # => "foo"
s.clear   # => ""
codepoints → array_of_integers Показать исходный код
static VALUE
rb_str_codepoints(VALUE str)
{
    VALUE ary = WANTARRAY("codepoints", rb_str_strlen(str));
    return rb_str_enumerate_codepoints(str, ary);
}

Возвращает массив кодовых точек в self; каждая кодовая точка — целое значение для символа:

'hello'.codepoints     # => [104, 101, 108, 108, 111]
'тест'.codepoints      # => [1090, 1077, 1089, 1090]
'こんにちは'.codepoints # => [12371, 12435, 12395, 12385, 12399]
concat(*objects) → string Показать исходный код
static VALUE
rb_str_concat_multi(int argc, VALUE *argv, VALUE str)
{
    str_modifiable(str);

    if (argc == 1) {
        return rb_str_concat(str, argv[0]);
    }
    else if (argc > 1) {
        int i;
        VALUE arg_str = rb_str_tmp_new(0);
        rb_enc_copy(arg_str, str);
        for (i = 0; i < argc; i++) {
            rb_str_concat(arg_str, argv[i]);
        }
        rb_str_buf_append(str, arg_str);
    }

    return str;
}

Конкатенирует каждый объект в objects со строкой self и возвращает self:

s = 'foo'
s.concat('bar', 'baz') # => "foobarbaz"
s                      # => "foobarbaz"

Для каждого данного объекта object являющегося целым числом, значение рассматривается как кодовая точка и преобразуется в символ перед конкатенацией:

s = 'foo'
s.concat(32, 'bar', 32, 'baz') # => "foo bar baz"

Связанно с: String#<<, которое принимает один аргумент.

count(*selectors) → integer Показать исходный код
static VALUE
rb_str_count(int argc, VALUE *argv, VALUE str)
{
    char table[TR_TABLE_SIZE];
    rb_encoding *enc = 0;
    VALUE del = 0, nodel = 0, tstr;
    char *s, *send;
    int i;
    int ascompat;
    size_t n = 0;

    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);

    tstr = argv[0];
    StringValue(tstr);
    enc = rb_enc_check(str, tstr);
    if (argc == 1) {
        const char *ptstr;
        if (RSTRING_LEN(tstr) == 1 && rb_enc_asciicompat(enc) &&
            (ptstr = RSTRING_PTR(tstr),
             ONIGENC_IS_ALLOWED_REVERSE_MATCH(enc, (const unsigned char *)ptstr, (const unsigned char *)ptstr+1)) &&
            !is_broken_string(str)) {
            int clen;
            unsigned char c = rb_enc_codepoint_len(ptstr, ptstr+1, &clen, enc);

            s = RSTRING_PTR(str);
            if (!s || RSTRING_LEN(str) == 0) return INT2FIX(0);
            send = RSTRING_END(str);
            while (s < send) {
                if (*(unsigned char*)s++ == c) n++;
            }
            return SIZET2NUM(n);
        }
    }

    tr_setup_table(tstr, table, TRUE, &del, &nodel, enc);
    for (i=1; i<argc; i++) {
        tstr = argv[i];
        StringValue(tstr);
        enc = rb_enc_check(str, tstr);
        tr_setup_table(tstr, table, FALSE, &del, &nodel, enc);
    }

    s = RSTRING_PTR(str);
    if (!s || RSTRING_LEN(str) == 0) return INT2FIX(0);
    send = RSTRING_END(str);
    ascompat = rb_enc_asciicompat(enc);
    while (s < send) {
        unsigned int c;

        if (ascompat && (c = *(unsigned char*)s) < 0x80) {
            if (table[c]) {
                n++;
            }
            s++;
        }
        else {
            int clen;
            c = rb_enc_codepoint_len(s, send, &clen, enc);
            if (tr_find(c, table, del, nodel)) {
                n++;
            }
            s += clen;
        }
    }

    return SIZET2NUM(n);
}

Возвращает общее количество символов в self, которые соответствуют заданным selectors (см. Выборки нескольких символов):

a = "hello world"
a.count "lo"                   #=> 5
a.count "lo", "o"              #=> 2
a.count "hello", "^l"          #=> 4
a.count "ej-m"                 #=> 4

"hello^world".count "\\^aeiou" #=> 4
"hello-world".count "a\\-eo"   #=> 4

c = "hello world\\r\\n"
c.count "\\"                   #=> 2
c.count "\\A"                  #=> 0
c.count "X-\\w"                #=> 3
crypt(salt_str) → new_string Показать исходный код
static VALUE
rb_str_crypt(VALUE str, VALUE salt)
{
#ifdef HAVE_CRYPT_R
    VALUE databuf;
    struct crypt_data *data;
#   define CRYPT_END() ALLOCV_END(databuf)
#else
    extern char *crypt(const char *, const char *);
#   define CRYPT_END() rb_nativethread_lock_unlock(&crypt_mutex.lock)
#endif
    VALUE result;
    const char *s, *saltp;
    char *res;
#ifdef BROKEN_CRYPT
    char salt_8bit_clean[3];
#endif

    StringValue(salt);
    mustnot_wchar(str);
    mustnot_wchar(salt);
    s = StringValueCStr(str);
    saltp = RSTRING_PTR(salt);
    if (RSTRING_LEN(salt) < 2 || !saltp[0] || !saltp[1]) {
        rb_raise(rb_eArgError, "salt too short (need >=2 bytes)");
    }

#ifdef BROKEN_CRYPT
    if (!ISASCII((unsigned char)saltp[0]) || !ISASCII((unsigned char)saltp[1])) {
        salt_8bit_clean[0] = saltp[0] & 0x7f;
        salt_8bit_clean[1] = saltp[1] & 0x7f;
        salt_8bit_clean[2] = '\0';
        saltp = salt_8bit_clean;
    }
#endif
#ifdef HAVE_CRYPT_R
    data = ALLOCV(databuf, sizeof(struct crypt_data));
# ifdef HAVE_STRUCT_CRYPT_DATA_INITIALIZED
    data->initialized = 0;
# endif
    res = crypt_r(s, saltp, data);
#else
    crypt_mutex_initialize();
    rb_nativethread_lock_lock(&crypt_mutex.lock);
    res = crypt(s, saltp);
#endif
    if (!res) {
        int err = errno;
        CRYPT_END();
        rb_syserr_fail(err, "crypt");
    }
    result = rb_str_new_cstr(res);
    CRYPT_END();
    return result;
}

Возвращает строку, сгенерированную вызовом стандартной библиотечной функции crypt(3) с str и salt_str в качестве аргументов в указанном порядке. Пожалуйста, больше не используйте этот метод. Он устарел; предоставляется только для обратной совместимости с ruby-скриптами прошлых дней. Его использование в современных программах нежелательно по нескольким причинам:

  • Поведение C-функции crypt(3) зависит от ОС. Сгенерированная строка не обладает переносимостью данных.

  • На некоторых ОС, таких как Mac OS, crypt(3) никогда не завершается ошибкой (т.е. тихо приводит к непредвиденным результатам).

  • На некоторых ОС, таких как Mac OS, crypt(3) не потокобезопасна.

  • Так называемое «традиционное» использование crypt(3) очень слабо. Согласно его man-странице, традиционный вывод crypt(3) Linux имеет только 2**56 вариантов; слишком легко взломать сегодня. И это поведение по умолчанию.

  • Для повышения устойчивости некоторые ОС реализуют так называемое «модульное» использование. Для этого нужно вручную выполнить сложную настройку параметра salt_str . Ошибки при генерации правильной строки соли обычно не приводят к ошибкам; опечатки в параметрах обычно не обнаруживаются.

    • Например, во втором вызове String#crypt в приведенном примере допущена ошибка: в «round=” отсутствует «s». Однако вызов не приводит к ошибке, и генерируется что-то неожиданное.

      "foo".crypt("$5$rounds=1000$salt$") # OK, proper usage
      "foo".crypt("$5$round=1000$salt$")  # Typo not detected
      
  • Даже в «модульном» режиме некоторые хеш-функции считаются устаревшими и больше не рекомендуются; например, модуль $1$ официально заброшен его автором: см. phk.freebsd.dk/sagas/md5crypt_eol/ . Для другого примера модуль $3$ считается полностью неисправным: см. man-страницу FreeBSD.

  • На некоторых ОС, таких как Mac OS, нет модульного режима. Однако, как указано выше, crypt(3) на Mac OS никогда не завершается ошибкой. Это означает, что даже если вы создадите правильную строку соли, она все равно сгенерирует традиционный DES-хеш, и вы об этом не узнаете.

    "foo".crypt("$5$rounds=1000$salt$") # => "$5fNPQMxC5j6."
    

Если по какой-то причине вы не можете перейти на другие современные безопасные алгоритмы хеширования паролей, установите gem string-crypt и require 'string/crypt' для продолжения использования данного метода.

-string → frozen_string

Возвращает замороженную, возможно уже существующую копию строки.

Возвращенная строка будет дедуплицирована, пока у нее не установлены никакие переменные экземпляра и она не является подклассом String.

String#dedup является псевдонимом для String#-@.

Псевдоним для: -@
delete(*selectors) → new_string Показать исходный код
static VALUE
rb_str_delete(int argc, VALUE *argv, VALUE str)
{
    str = str_duplicate(rb_cString, str);
    rb_str_delete_bang(argc, argv, str);
    return str;
}

Возвращает копию self со символами, указанными в selectors удаленными (см. Выборки нескольких символов):

"hello".delete "l","lo"        #=> "heo"
"hello".delete "lo"            #=> "he"
"hello".delete "aeiou", "^e"   #=> "hell"
"hello".delete "ej-m"          #=> "ho"
delete!(*selectors) → self or nil Показать исходный код
static VALUE
rb_str_delete_bang(int argc, VALUE *argv, VALUE str)
{
    char squeez[TR_TABLE_SIZE];
    rb_encoding *enc = 0;
    char *s, *send, *t;
    VALUE del = 0, nodel = 0;
    int modify = 0;
    int i, ascompat, cr;

    if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return Qnil;
    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
    for (i=0; i<argc; i++) {
        VALUE s = argv[i];

        StringValue(s);
        enc = rb_enc_check(str, s);
        tr_setup_table(s, squeez, i==0, &del, &nodel, enc);
    }

    str_modify_keep_cr(str);
    ascompat = rb_enc_asciicompat(enc);
    s = t = RSTRING_PTR(str);
    send = RSTRING_END(str);
    cr = ascompat ? ENC_CODERANGE_7BIT : ENC_CODERANGE_VALID;
    while (s < send) {
        unsigned int c;
        int clen;

        if (ascompat && (c = *(unsigned char*)s) < 0x80) {
            if (squeez[c]) {
                modify = 1;
            }
            else {
                if (t != s) *t = c;
                t++;
            }
            s++;
        }
        else {
            c = rb_enc_codepoint_len(s, send, &clen, enc);

            if (tr_find(c, squeez, del, nodel)) {
                modify = 1;
            }
            else {
                if (t != s) rb_enc_mbcput(c, t, enc);
                t += clen;
                if (cr == ENC_CODERANGE_7BIT) cr = ENC_CODERANGE_VALID;
            }
            s += clen;
        }
    }
    TERM_FILL(t, TERM_LEN(str));
    STR_SET_LEN(str, t - RSTRING_PTR(str));
    ENC_CODERANGE_SET(str, cr);

    if (modify) return str;
    return Qnil;
}

Подобно String#delete, но изменяет self на месте. Возвращает self если изменения были внесены, nil в противном случае.

END_OF_DOCUMENT_MARKER
delete_prefix(prefix) → new_string Show source
static VALUE
rb_str_delete_prefix(VALUE str, VALUE prefix)
{
    long prefixlen;

    prefixlen = deleted_prefix_length(str, prefix);
    if (prefixlen <= 0) return str_duplicate(rb_cString, str);

    return rb_str_subseq(str, prefixlen, RSTRING_LEN(str) - prefixlen);
}

Возвращает копию self с удалённой начальной подстрокой prefix:

'hello'.delete_prefix('hel')      # => "lo"
'hello'.delete_prefix('llo')      # => "hello"
'тест'.delete_prefix('те')        # => "ст"
'こんにちは'.delete_prefix('こん')  # => "にちは"

Связанные: String#delete_prefix!, String#delete_suffix.

delete_prefix!(prefix) → self or nil Show source
static VALUE
rb_str_delete_prefix_bang(VALUE str, VALUE prefix)
{
    long prefixlen;
    str_modify_keep_cr(str);

    prefixlen = deleted_prefix_length(str, prefix);
    if (prefixlen <= 0) return Qnil;

    return rb_str_drop_bytes(str, prefixlen);
}

Как String#delete_prefix, за исключением того, что self изменяется на месте. Возвращает self, если префикс удалён, nil в противном случае.

delete_suffix(suffix) → new_string Show source
static VALUE
rb_str_delete_suffix(VALUE str, VALUE suffix)
{
    long suffixlen;

    suffixlen = deleted_suffix_length(str, suffix);
    if (suffixlen <= 0) return str_duplicate(rb_cString, str);

    return rb_str_subseq(str, 0, RSTRING_LEN(str) - suffixlen);
}

Возвращает копию self с удалённой конечной подстрокой suffix:

'hello'.delete_suffix('llo')      # => "he"
'hello'.delete_suffix('hel')      # => "hello"
'тест'.delete_suffix('ст')        # => "те"
'こんにちは'.delete_suffix('ちは')  # => "こんに"

Связанные: String#delete_suffix!, String#delete_prefix.

delete_suffix!(suffix) → self or nil Show source
static VALUE
rb_str_delete_suffix_bang(VALUE str, VALUE suffix)
{
    long olen, suffixlen, len;
    str_modifiable(str);

    suffixlen = deleted_suffix_length(str, suffix);
    if (suffixlen <= 0) return Qnil;

    olen = RSTRING_LEN(str);
    str_modify_keep_cr(str);
    len = olen - suffixlen;
    STR_SET_LEN(str, len);
    TERM_FILL(&RSTRING_PTR(str)[len], TERM_LEN(str));
    if (ENC_CODERANGE(str) != ENC_CODERANGE_7BIT) {
        ENC_CODERANGE_CLEAR(str);
    }
    return str;
}

Как String#delete_suffix, за исключением того, что self изменяется на месте. Возвращает self, если суффикс удалён, nil в противном случае.

downcase(*options) → string Show source
static VALUE
rb_str_downcase(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    OnigCaseFoldType flags = ONIGENC_CASE_DOWNCASE;
    VALUE ret;

    flags = check_case_options(argc, argv, flags);
    enc = str_true_enc(str);
    if (case_option_single_p(flags, enc, str)) {
        ret = rb_str_new(RSTRING_PTR(str), RSTRING_LEN(str));
        str_enc_copy(ret, str);
        downcase_single(ret);
    }
    else if (flags&ONIGENC_CASE_ASCII_ONLY) {
        ret = rb_str_new(0, RSTRING_LEN(str));
        rb_str_ascii_casemap(str, ret, &flags, enc);
    }
    else {
        ret = rb_str_casemap(str, &flags, enc);
    }

    return ret;
}

Возвращает строку, содержащую символы в нижнем регистре в self:

s = 'Hello World!' # => "Hello World!"
s.downcase         # => "hello world!"

Регистр может быть затронут заданными options; см. Case Mapping.

Связанные: String#downcase!, String#upcase, String#upcase!.

downcase!(*options) → self or nil Show source
static VALUE
rb_str_downcase_bang(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    OnigCaseFoldType flags = ONIGENC_CASE_DOWNCASE;

    flags = check_case_options(argc, argv, flags);
    str_modify_keep_cr(str);
    enc = str_true_enc(str);
    if (case_option_single_p(flags, enc, str)) {
        if (downcase_single(str))
            flags |= ONIGENC_CASE_MODIFIED;
    }
    else if (flags&ONIGENC_CASE_ASCII_ONLY)
        rb_str_ascii_casemap(str, str, &flags, enc);
    else
        str_shared_replace(str, rb_str_casemap(str, &flags, enc));

    if (ONIGENC_CASE_MODIFIED&flags) return str;
    return Qnil;
}

Переводит символы в self в нижний регистр; возвращает self, если были внесены какие-либо изменения, nil в противном случае:

s = 'Hello World!' # => "Hello World!"
s.downcase!        # => "hello world!"
s                  # => "hello world!"
s.downcase!        # => nil

Регистр может быть затронут заданными options; см. Case Mapping.

Связанные: String#downcase, String#upcase, String#upcase!.

dump → string Show source
VALUE
rb_str_dump(VALUE str)
{
    int encidx = rb_enc_get_index(str);
    rb_encoding *enc = rb_enc_from_index(encidx);
    long len;
    const char *p, *pend;
    char *q, *qend;
    VALUE result;
    int u8 = (encidx == rb_utf8_encindex());
    static const char nonascii_suffix[] = ".dup.force_encoding(\"%s\")";

    len = 2;                    /* "" */
    if (!rb_enc_asciicompat(enc)) {
        len += strlen(nonascii_suffix) - rb_strlen_lit("%s");
        len += strlen(enc->name);
    }

    p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
    while (p < pend) {
        int clen;
        unsigned char c = *p++;

        switch (c) {
          case '"':  case '\\':
          case '\n': case '\r':
          case '\t': case '\f':
          case '\013': case '\010': case '\007': case '\033':
            clen = 2;
            break;

          case '#':
            clen = IS_EVSTR(p, pend) ? 2 : 1;
            break;

          default:
            if (ISPRINT(c)) {
                clen = 1;
            }
            else {
                if (u8 && c > 0x7F) {   /* \u notation */
                    int n = rb_enc_precise_mbclen(p-1, pend, enc);
                    if (MBCLEN_CHARFOUND_P(n)) {
                        unsigned int cc = rb_enc_mbc_to_codepoint(p-1, pend, enc);
                        if (cc <= 0xFFFF)
                            clen = 6;  /* \uXXXX */
                        else if (cc <= 0xFFFFF)
                            clen = 9;  /* \u{XXXXX} */
                        else
                            clen = 10; /* \u{XXXXXX} */
                        p += MBCLEN_CHARFOUND_LEN(n)-1;
                        break;
                    }
                }
                clen = 4;       /* \xNN */
            }
            break;
        }

        if (clen > LONG_MAX - len) {
            rb_raise(rb_eRuntimeError, "string size too big");
        }
        len += clen;
    }

    result = rb_str_new(0, len);
    p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
    q = RSTRING_PTR(result); qend = q + len + 1;

    *q++ = '"';
    while (p < pend) {
        unsigned char c = *p++;

        if (c == '"' || c == '\\') {
            *q++ = '\\';
            *q++ = c;
        }
        else if (c == '#') {
            if (IS_EVSTR(p, pend)) *q++ = '\\';
            *q++ = '#';
        }
        else if (c == '\n') {
            *q++ = '\\';
            *q++ = 'n';
        }
        else if (c == '\r') {
            *q++ = '\\';
            *q++ = 'r';
        }
        else if (c == '\t') {
            *q++ = '\\';
            *q++ = 't';
        }
        else if (c == '\f') {
            *q++ = '\\';
            *q++ = 'f';
        }
        else if (c == '\013') {
            *q++ = '\\';
            *q++ = 'v';
        }
        else if (c == '\010') {
            *q++ = '\\';
            *q++ = 'b';
        }
        else if (c == '\007') {
            *q++ = '\\';
            *q++ = 'a';
        }
        else if (c == '\033') {
            *q++ = '\\';
            *q++ = 'e';
        }
        else if (ISPRINT(c)) {
            *q++ = c;
        }
        else {
            *q++ = '\\';
            if (u8) {
                int n = rb_enc_precise_mbclen(p-1, pend, enc) - 1;
                if (MBCLEN_CHARFOUND_P(n)) {
                    int cc = rb_enc_mbc_to_codepoint(p-1, pend, enc);
                    p += n;
                    if (cc <= 0xFFFF)
                        snprintf(q, qend-q, "u%04X", cc);    /* \uXXXX */
                    else
                        snprintf(q, qend-q, "u{%X}", cc);  /* \u{XXXXX} or \u{XXXXXX} */
                    q += strlen(q);
                    continue;
                }
            }
            snprintf(q, qend-q, "x%02X", c);
            q += 3;
        }
    }
    *q++ = '"';
    *q = '\0';
    if (!rb_enc_asciicompat(enc)) {
        snprintf(q, qend-q, nonascii_suffix, enc->name);
        encidx = rb_ascii8bit_encindex();
    }
    /* result from dump is ASCII */
    rb_enc_associate_index(result, encidx);
    ENC_CODERANGE_SET(result, ENC_CODERANGE_7BIT);
    return result;
}

Возвращает печатную версию self, заключённую в двойные кавычки, со специальными символами, экранированными, и с непечатными символами, заменёнными шестнадцатеричной нотацией:

"hello \n ''".dump    # => "\"hello \\n ''\""
"\f\x00\xff\\\"".dump # => "\"\\f\\x00\\xFF\\\\\\\"\""

Связанные: String#undump (обратное к String#dump).

each_byte {|byte| ... } → self Show source
each_byte → enumerator
static VALUE
rb_str_each_byte(VALUE str)
{
    RETURN_SIZED_ENUMERATOR(str, 0, 0, rb_str_each_byte_size);
    return rb_str_enumerate_bytes(str, 0);
}

Вызывает заданный блок с каждым последующим байтом из self; возвращает self:

'hello'.each_byte {|byte| print byte, ' ' }
print "\n"
'тест'.each_byte {|byte| print byte, ' ' }
print "\n"
'こんにちは'.each_byte {|byte| print byte, ' ' }
print "\n"

Вывод:

104 101 108 108 111
209 130 208 181 209 129 209 130
227 129 147 227 130 147 227 129 171 227 129 161 227 129 175

Возвращает перечислитель, если блок не задан.

each_char {|c| ... } → self Show source
each_char → enumerator
static VALUE
rb_str_each_char(VALUE str)
{
    RETURN_SIZED_ENUMERATOR(str, 0, 0, rb_str_each_char_size);
    return rb_str_enumerate_chars(str, 0);
}

Вызывает заданный блок с каждым последующим символом из self; возвращает self:

'hello'.each_char {|char| print char, ' ' }
print "\n"
'тест'.each_char {|char| print char, ' ' }
print "\n"
'こんにちは'.each_char {|char| print char, ' ' }
print "\n"

Вывод:

h e l l o
т е с т
こ ん に ち は

Возвращает перечислитель, если блок не задан.

each_codepoint {|integer| ... } → self Show source
each_codepoint → enumerator
static VALUE
rb_str_each_codepoint(VALUE str)
{
    RETURN_SIZED_ENUMERATOR(str, 0, 0, rb_str_each_char_size);
    return rb_str_enumerate_codepoints(str, 0);
}

Вызывает заданный блок с каждым последующим кодовым значением из self; каждое кодовое значение - это целое число для символа; возвращает self:

'hello'.each_codepoint {|codepoint| print codepoint, ' ' }
print "\n"
'тест'.each_codepoint {|codepoint| print codepoint, ' ' }
print "\n"
'こんにちは'.each_codepoint {|codepoint| print codepoint, ' ' }
print "\n"

Вывод:

104 101 108 108 111
1090 1077 1089 1090
12371 12435 12395 12385 12399

Возвращает перечислитель, если блок не задан.

each_grapheme_cluster {|gc| ... } → self Show source
each_grapheme_cluster → enumerator
static VALUE
rb_str_each_grapheme_cluster(VALUE str)
{
    RETURN_SIZED_ENUMERATOR(str, 0, 0, rb_str_each_grapheme_cluster_size);
    return rb_str_enumerate_grapheme_clusters(str, 0);
}

Вызывает заданный блок с каждой последующей графемой из self (см. Unicode Grapheme Cluster Boundaries); возвращает self:

s = "\u0061\u0308-pqr-\u0062\u0308-xyz-\u0063\u0308" # => "ä-pqr-b̈-xyz-c̈"
s.each_grapheme_cluster {|gc| print gc, ' ' }

Вывод:

ä - p q r - b̈ - x y z - c̈

Возвращает перечислитель, если блок не задан.

each_line(line_sep = $/, chomp: false) {|substring| ... } → self Show source
each_line(line_sep = $/, chomp: false) → enumerator
static VALUE
rb_str_each_line(int argc, VALUE *argv, VALUE str)
{
    RETURN_SIZED_ENUMERATOR(str, argc, argv, 0);
    return rb_str_enumerate_lines(argc, argv, str, 0);
}

Если задан блок, формирует подстроки («строки»), которые являются результатом разделения self на каждое вхождение заданного разделителя строк line_sep; передаёт каждую строку в блок; возвращает self:

s = <<~EOT
This is the first line.
This is line two.

This is line four.
This is line five.
EOT

s.each_line {|line| p line }

Вывод:

"This is the first line.\n"
"This is line two.\n"
"\n"
"This is line four.\n"
"This is line five.\n"

С другим line_sep:

s.each_line(' is ') {|line| p line }

Вывод:

"This is "
"the first line.\nThis is "
"line two.\n\nThis is "
"line four.\nThis is "
"line five.\n"

С chomp как true, удаляет конечный line_sep из каждой строки:

s.each_line(chomp: true) {|line| p line }

Вывод:

"This is the first line."
"This is line two."
""
"This is line four."
"This is line five."

С пустой строкой как line_sep, формирует и передаёт «абзацы», разделяя их на каждое вхождение двух или более символов новой строки:

s.each_line('') {|line| p line }

Вывод:

"This is the first line.\nThis is line two.\n\n"
"This is line four.\nThis is line five.\n"

Если блок не задан, возвращает перечислитель.

empty? → true or false Show source
static VALUE
rb_str_empty(VALUE str)
{
    return RBOOL(RSTRING_LEN(str) == 0);
}

Возвращает true, если длина self равна нулю, false в противном случае:

"hello".empty? # => false
" ".empty? # => false
"".empty? # => true
encode(dst_encoding = Encoding.default_internal, **enc_opts) → string Показать исходный код
encode(dst_encoding, src_encoding, **enc_opts) → string
# File transcode.rdoc, line 48
def encode(dst_encoding = Encoding.default_internal, **enc_opts)
  # Pseudo code
  Primitive.str_encode(...)
end

Возвращает копию self, преобразованную с помощью кодировки, определенной в dst_encoding. По умолчанию, генерирует исключение, если self содержит недействительный байт или символ, не определенный в dst_encoding; это поведение можно изменить с помощью опций кодирования; см. ниже.

Без аргументов:

  • Использует ту же кодировку, если Encoding.default_internal равна nil (по умолчанию):

    Encoding.default_internal # => nil
    s = "Ruby\x99".force_encoding('Windows-1252')
    s.encoding                # => #<Encoding:Windows-1252>
    s.bytes                   # => [82, 117, 98, 121, 153]
    t = s.encode              # => "Ruby\x99"
    t.encoding                # => #<Encoding:Windows-1252>
    t.bytes                   # => [82, 117, 98, 121, 226, 132, 162]
    
  • В противном случае, использует кодировку Encoding.default_internal:

    Encoding.default_internal = 'UTF-8'
    t = s.encode              # => "Ruby™"
    t.encoding                # => #<Encoding:UTF-8>
    

С аргументом dst_encoding, использует эту кодировку:

s = "Ruby\x99".force_encoding('Windows-1252')
s.encoding            # => #<Encoding:Windows-1252>
t = s.encode('UTF-8') # => "Ruby™"
t.encoding            # => #<Encoding:UTF-8>

С аргументами dst_encoding и src_encoding интерпретирует self используя src_encoding, кодирует новую строку используя dst_encoding:

s = "Ruby\x99"
t = s.encode('UTF-8', 'Windows-1252') # => "Ruby™"
t.encoding                            # => #<Encoding:UTF-8>

Необязательные ключевые аргументы enc_opts задают параметры кодирования; см. Опции кодирования.

encode!(dst_encoding = Encoding.default_internal, **enc_opts) → self Показать исходный код
encode!(dst_encoding, src_encoding, **enc_opts) → self
static VALUE
str_encode_bang(int argc, VALUE *argv, VALUE str)
{
    VALUE newstr;
    int encidx;

    rb_check_frozen(str);

    newstr = str;
    encidx = str_transcode(argc, argv, &newstr);

    if (encidx < 0) return str;
    if (newstr == str) {
        rb_enc_associate_index(str, encidx);
        return str;
    }
    rb_str_shared_replace(str, newstr);
    return str_encode_associate(str, encidx);
}

Как encode, но применяет изменения кодировки к self; возвращает self.

encoding → encoding Показать исходный код
VALUE
rb_obj_encoding(VALUE obj)
{
    int idx = rb_enc_get_index(obj);
    if (idx < 0) {
        rb_raise(rb_eTypeError, "unknown encoding");
    }
    return rb_enc_from_encoding_index(idx & ENC_INDEX_MASK);
}

Возвращает объект Encoding, который представляет кодировку obj.

end_with?(*strings) → true or false Показать исходный код
static VALUE
rb_str_end_with(int argc, VALUE *argv, VALUE str)
{
    int i;
    char *p, *s, *e;
    rb_encoding *enc;

    for (i=0; i<argc; i++) {
        VALUE tmp = argv[i];
        long slen, tlen;
        StringValue(tmp);
        enc = rb_enc_check(str, tmp);
        if ((tlen = RSTRING_LEN(tmp)) == 0) return Qtrue;
        if ((slen = RSTRING_LEN(str)) < tlen) continue;
        p = RSTRING_PTR(str);
        e = p + slen;
        s = e - tlen;
        if (rb_enc_left_char_head(p, s, e, enc) != s)
            continue;
        if (memcmp(s, RSTRING_PTR(tmp), RSTRING_LEN(tmp)) == 0)
            return Qtrue;
    }
    return Qfalse;
}

Возвращает значение, указывающее, заканчивается ли self любой из переданных strings.

Возвращает true , если какая-либо строка соответствует концу, false в противном случае:

'hello'.end_with?('ello')               #=> true
'hello'.end_with?('heaven', 'ello')     #=> true
'hello'.end_with?('heaven', 'paradise') #=> false
'тест'.end_with?('т')                   # => true
'こんにちは'.end_with?('は')              # => true

Связанно с: String#start_with?.

eql?(object) → true or false Показать исходный код
MJIT_FUNC_EXPORTED VALUE
rb_str_eql(VALUE str1, VALUE str2)
{
    if (str1 == str2) return Qtrue;
    if (!RB_TYPE_P(str2, T_STRING)) return Qfalse;
    return rb_str_eql_internal(str1, str2);
}

Возвращает true , если object имеет одинаковую длину и содержимое, как self; false в противном случае:

s = 'foo'
s.eql?('foo') # => true
s.eql?('food') # => false
s.eql?('FOO') # => false

Возвращает false , если кодировки двух строк несовместимы:

"\u{e4 f6 fc}".encode("ISO-8859-1").eql?("\u{c4 d6 dc}") # => false
force_encoding(encoding) → self Показать исходный код
static VALUE
rb_str_force_encoding(VALUE str, VALUE enc)
{
    str_modifiable(str);
    rb_enc_associate(str, rb_to_encoding(enc));
    ENC_CODERANGE_CLEAR(str);
    return str;
}

Изменяет кодировку self на encoding, что может быть именем кодировки строки или объектом Encoding; возвращает self:

s = 'łał'
s.bytes                   # => [197, 130, 97, 197, 130]
s.encoding                # => #<Encoding:UTF-8>
s.force_encoding('ascii') # => "\xC5\x82a\xC5\x82"
s.encoding                # => #<Encoding:US-ASCII>

Не изменяет исходные байты:

s.bytes                   # => [197, 130, 97, 197, 130]

Производит изменение, даже если заданная encoding является недопустимой для self (как и изменение выше):

s.valid_encoding?                 # => false
s.force_encoding(Encoding::UTF_8) # => "łał"
s.valid_encoding?                 # => true
freeze() Показать исходный код
VALUE
rb_str_freeze(VALUE str)
{
    if (OBJ_FROZEN(str)) return str;
    rb_str_resize(str, RSTRING_LEN(str));
    return rb_obj_freeze(str);
}
getbyte(index) → integer or nil Показать исходный код
static VALUE
rb_str_getbyte(VALUE str, VALUE index)
{
    long pos = NUM2LONG(index);

    if (pos < 0)
        pos += RSTRING_LEN(str);
    if (pos < 0 ||  RSTRING_LEN(str) <= pos)
        return Qnil;

    return INT2FIX((unsigned char)RSTRING_PTR(str)[pos]);
}

Возвращает байт по нулевому индексу index в виде целого числа или nil , если index выходит за пределы диапазона:

s = 'abcde'   # => "abcde"
s.getbyte(0)  # => 97
s.getbyte(-1) # => 101
s.getbyte(5)  # => nil

Связанно с: String#setbyte.

grapheme_clusters → array_of_grapheme_clusters Показать исходный код
static VALUE
rb_str_grapheme_clusters(VALUE str)
{
    VALUE ary = WANTARRAY("grapheme_clusters", rb_str_strlen(str));
    return rb_str_enumerate_grapheme_clusters(str, ary);
}

Возвращает массив графемных кластеров в self (см. Границы графемных кластеров Unicode):

s = "\u0061\u0308-pqr-\u0062\u0308-xyz-\u0063\u0308" # => "ä-pqr-b̈-xyz-c̈"
s.grapheme_clusters
# => ["ä", "-", "p", "q", "r", "-", "b̈", "-", "x", "y", "z", "-", "c̈"]
gsub(pattern, replacement) → new_string Показать исходный код
gsub(pattern) {|match| ... } → new_string
gsub(pattern) → enumerator
static VALUE
rb_str_gsub(int argc, VALUE *argv, VALUE str)
{
    return str_gsub(argc, argv, str, 0);
}

Возвращает копию self со всеми вхождениями заданного pattern замененными.

См. Методы замены.

Возвращает Enumerator, если нет replacement и нет блока.

Связанно с: String#sub, String#sub!, String#gsub!.

gsub!(pattern, replacement) → self or nil Показать исходный код
gsub!(pattern) {|match| ... } → self or nil
gsub!(pattern) → an_enumerator
static VALUE
rb_str_gsub_bang(int argc, VALUE *argv, VALUE str)
{
    str_modify_keep_cr(str);
    return str_gsub(argc, argv, str, 1);
}

Выполняет указанные замены подстроки(ей) в self; возвращает self , если замена произошла, nil в противном случае.

См. Методы замены.

Возвращает Enumerator, если нет replacement и нет блока.

Связанно с: String#sub, String#gsub, String#sub!.

hash → integer Показать исходный код
static VALUE
rb_str_hash_m(VALUE str)
{
    st_index_t hval = rb_str_hash(str);
    return ST2FIX(hval);
}

Возвращает целочисленное значение хэша для self. Значение основано на длине, содержимом и кодировке self.

Связанно с: Object#hash.

hex → integer Показать исходный код
static VALUE
rb_str_hex(VALUE str)
{
    return rb_str_to_inum(str, 16, FALSE);
}

Интерпретирует ведущую подстроку self как строку шестнадцатеричных цифр (с необязательным знаком и необязательным 0x) и возвращает соответствующее число; возвращает ноль, если такой ведущей подстроки нет:

'0x0a'.hex        # => 10
'-1234'.hex       # => -4660
'0'.hex           # => 0
'non-numeric'.hex # => 0

Связанно с: String#oct.

include? other_string → true or false Показать исходный код
VALUE
rb_str_include(VALUE str, VALUE arg)
{
    long i;

    StringValue(arg);
    i = rb_str_index(str, arg, 0);

    return RBOOL(i != -1);
}

Возвращает true , если self содержит other_string, false в противном случае:

s = 'foo'
s.include?('f')    # => true
s.include?('fo')   # => true
s.include?('food') # => false
index(substring, offset = 0) → целое число или nil Показать исходный код
index(regexp, offset = 0) → целое число или nil
static VALUE
rb_str_index_m(int argc, VALUE *argv, VALUE str)
{
    VALUE sub;
    VALUE initpos;
    long pos;

    if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) {
        pos = NUM2LONG(initpos);
    }
    else {
        pos = 0;
    }
    if (pos < 0) {
        pos += str_strlen(str, NULL);
        if (pos < 0) {
            if (RB_TYPE_P(sub, T_REGEXP)) {
                rb_backref_set(Qnil);
            }
            return Qnil;
        }
    }

    if (RB_TYPE_P(sub, T_REGEXP)) {
        if (pos > str_strlen(str, NULL))
            return Qnil;
        pos = str_offset(RSTRING_PTR(str), RSTRING_END(str), pos,
                         rb_enc_check(str, sub), single_byte_optimizable(str));

        if (rb_reg_search(sub, str, pos, 0) < 0) {
            return Qnil;
        }
        else {
            VALUE match = rb_backref_get();
            struct re_registers *regs = RMATCH_REGS(match);
            pos = rb_str_sublen(str, BEG(0));
            return LONG2NUM(pos);
        }
    }
    else {
        StringValue(sub);
        pos = rb_str_index(str, sub, pos);
        pos = rb_str_sublen(str, pos);
    }

    if (pos == -1) return Qnil;
    return LONG2NUM(pos);
}

Возвращает целочисленный индекс первого совпадения для данного аргумента или nil если совпадений нет; поиск self выполняется вперёд и начинается с позиции offset (в символах).

При строковом аргументе substring, возвращает индекс первой совпадающей подстроки в self:

'foo'.index('f')         # => 0
'foo'.index('o')         # => 1
'foo'.index('oo')        # => 1
'foo'.index('ooo')       # => nil
'тест'.index('с')        # => 2
'こんにちは'.index('ち')   # => 3

При аргументе Regexp regexp, возвращает индекс первого совпадения в self:

'foo'.index(/o./) # => 1
'foo'.index(/.o/) # => 0

При положительном целочисленном аргументе offset, поиск начинается с позиции offset:

'foo'.index('o', 1)        # => 1
'foo'.index('o', 2)        # => 2
'foo'.index('o', 3)        # => nil
'тест'.index('с', 1)       # => 2
'こんにちは'.index('ち', 2)  # => 3

При отрицательном целочисленном аргументе offset, позиция поиска выбирается путём обратного отсчёта от конца self:

'foo'.index('o', -1)  # => 2
'foo'.index('o', -2)  # => 1
'foo'.index('o', -3)  # => 1
'foo'.index('o', -4)  # => nil
'foo'.index(/o./, -2) # => 1
'foo'.index(/.o/, -2) # => 1

Связанно с: String#rindex.

initialize_copy(other_string) -> self Показать исходный код
VALUE
rb_str_replace(VALUE str, VALUE str2)
{
    str_modifiable(str);
    if (str == str2) return str;

    StringValue(str2);
    str_discard(str);
    return str_replace(str, str2);
}

Заменяет содержимое self содержимым other_string:

s = 'foo'        # => "foo"
s.replace('bar') # => "bar"
Также алиас: replace
insert(index, other_string) → self Показать исходный код
static VALUE
rb_str_insert(VALUE str, VALUE idx, VALUE str2)
{
    long pos = NUM2LONG(idx);

    if (pos == -1) {
        return rb_str_append(str, str2);
    }
    else if (pos < 0) {
        pos++;
    }
    rb_str_splice(str, pos, 0, str2);
    return str;
}

Вставляет указанную other_string в self; возвращает self.

Если целое число index положительное, вставляет other_string по смещению index:

'foo'.insert(1, 'bar') # => "fbaroo"

Если целое число index отрицательное, отсчитывает назад от конца self и вставляет other_string по смещению index+1 (то есть, после self[index]):

'foo'.insert(-2, 'bar') # => "fobaro"
inspect → строка Показать исходный код
VALUE
rb_str_inspect(VALUE str)
{
    int encidx = ENCODING_GET(str);
    rb_encoding *enc = rb_enc_from_index(encidx);
    const char *p, *pend, *prev;
    char buf[CHAR_ESC_LEN + 1];
    VALUE result = rb_str_buf_new(0);
    rb_encoding *resenc = rb_default_internal_encoding();
    int unicode_p = rb_enc_unicode_p(enc);
    int asciicompat = rb_enc_asciicompat(enc);

    if (resenc == NULL) resenc = rb_default_external_encoding();
    if (!rb_enc_asciicompat(resenc)) resenc = rb_usascii_encoding();
    rb_enc_associate(result, resenc);
    str_buf_cat2(result, "\"");

    p = RSTRING_PTR(str); pend = RSTRING_END(str);
    prev = p;
    while (p < pend) {
        unsigned int c, cc;
        int n;

        n = rb_enc_precise_mbclen(p, pend, enc);
        if (!MBCLEN_CHARFOUND_P(n)) {
            if (p > prev) str_buf_cat(result, prev, p - prev);
            n = rb_enc_mbminlen(enc);
            if (pend < p + n)
                n = (int)(pend - p);
            while (n--) {
                snprintf(buf, CHAR_ESC_LEN, "\\x%02X", *p & 0377);
                str_buf_cat(result, buf, strlen(buf));
                prev = ++p;
            }
            continue;
        }
        n = MBCLEN_CHARFOUND_LEN(n);
        c = rb_enc_mbc_to_codepoint(p, pend, enc);
        p += n;
        if ((asciicompat || unicode_p) &&
          (c == '"'|| c == '\\' ||
            (c == '#' &&
             p < pend &&
             MBCLEN_CHARFOUND_P(rb_enc_precise_mbclen(p,pend,enc)) &&
             (cc = rb_enc_codepoint(p,pend,enc),
              (cc == '$' || cc == '@' || cc == '{'))))) {
            if (p - n > prev) str_buf_cat(result, prev, p - n - prev);
            str_buf_cat2(result, "\\");
            if (asciicompat || enc == resenc) {
                prev = p - n;
                continue;
            }
        }
        switch (c) {
          case '\n': cc = 'n'; break;
          case '\r': cc = 'r'; break;
          case '\t': cc = 't'; break;
          case '\f': cc = 'f'; break;
          case '\013': cc = 'v'; break;
          case '\010': cc = 'b'; break;
          case '\007': cc = 'a'; break;
          case 033: cc = 'e'; break;
          default: cc = 0; break;
        }
        if (cc) {
            if (p - n > prev) str_buf_cat(result, prev, p - n - prev);
            buf[0] = '\\';
            buf[1] = (char)cc;
            str_buf_cat(result, buf, 2);
            prev = p;
            continue;
        }
        /* The special casing of 0x85 (NEXT_LINE) here is because
         * Oniguruma historically treats it as printable, but it
         * doesn't match the print POSIX bracket class or character
         * property in regexps.
         *
         * See Ruby Bug #16842 for details:
         * https://bugs.ruby-lang.org/issues/16842
         */
        if ((enc == resenc && rb_enc_isprint(c, enc) && c != 0x85) ||
            (asciicompat && rb_enc_isascii(c, enc) && ISPRINT(c))) {
            continue;
        }
        else {
            if (p - n > prev) str_buf_cat(result, prev, p - n - prev);
            rb_str_buf_cat_escaped_char(result, c, unicode_p);
            prev = p;
            continue;
        }
    }
    if (p > prev) str_buf_cat(result, prev, p - prev);
    str_buf_cat2(result, "\"");

    return result;
}

Возвращает удобочитаемый вид self, заключённый в двойные кавычки, и со специальными символами, экранированными:

s = "foo\tbar\tbaz\n"
s.inspect
# => "\"foo\\tbar\\tbaz\\n\""
intern → символ Показать исходный код
VALUE
rb_str_intern(VALUE str)
{
    VALUE sym;
#if USE_SYMBOL_GC
    rb_encoding *enc, *ascii;
    int type;
#else
    ID id;
#endif
    GLOBAL_SYMBOLS_ENTER(symbols);
    {
        sym = lookup_str_sym_with_lock(symbols, str);

        if (sym) {
            // ok
        }
        else {
#if USE_SYMBOL_GC
            enc = rb_enc_get(str);
            ascii = rb_usascii_encoding();
            if (enc != ascii && sym_check_asciionly(str)) {
                str = rb_str_dup(str);
                rb_enc_associate(str, ascii);
                OBJ_FREEZE(str);
                enc = ascii;
            }
            else {
                str = rb_str_dup(str);
                OBJ_FREEZE(str);
            }
            str = rb_fstring(str);
            type = rb_str_symname_type(str, IDSET_ATTRSET_FOR_INTERN);
            if (type < 0) type = ID_JUNK;
            sym = dsymbol_alloc(symbols, rb_cSymbol, str, enc, type);
#else
            id = intern_str(str, 0);
            sym = ID2SYM(id);
#endif
        }
    }
    GLOBAL_SYMBOLS_LEAVE();
    return sym;
}

Возвращает Symbol, соответствующий str, создавая символ, если он ранее не существовал. См. Symbol#id2name.

"Koala".intern         #=> :Koala
s = 'cat'.to_sym       #=> :cat
s == :cat              #=> true
s = '@cat'.to_sym      #=> :@cat
s == :@cat             #=> true

Это также можно использовать для создания символов, которые нельзя представить с помощью :xxx обозначения.

'cat and dog'.to_sym   #=> :"cat and dog"
Также алиас: to_sym
String#iseuc → true или false Показать исходный код
# File ext/nkf/lib/kconv.rb, line 264
def iseuc;    Kconv.iseuc(self) end

Возвращает, является ли кодировка self EUC-JP или нет.

String#isjis → true или false Показать исходный код
# File ext/nkf/lib/kconv.rb, line 276
def isjis;    Kconv.isjis(self) end

Возвращает, является ли кодировка self ISO-2022-JP или нет.

String#issjis → true или false Показать исходный код
# File ext/nkf/lib/kconv.rb, line 270
def issjis;   Kconv.issjis(self) end

Возвращает, является ли кодировка self Shift_JIS или нет.

String#isutf8 → true или false Показать исходный код
# File ext/nkf/lib/kconv.rb, line 282
def isutf8;   Kconv.isutf8(self) end

Возвращает, является ли кодировка self UTF-8 или нет.

String#kconv(to_enc, from_enc) Показать исходный код
# File ext/nkf/lib/kconv.rb, line 205
def kconv(to_enc, from_enc=nil)
  from_enc = self.encoding if !from_enc && self.encoding != Encoding.list[0]
  Kconv::kconv(self, to_enc, from_enc)
end

Преобразовать self в to_enc. to_enc и from_enc задаются как константы объектов Kconv или Encoding.

length → целое число Показать исходный код
VALUE
rb_str_length(VALUE str)
{
    return LONG2NUM(str_strlen(str, NULL));
}

Возвращает количество символов (а не байтов) в self:

'foo'.length        # => 3
'тест'.length       # => 4
'こんにちは'.length   # => 5

В отличие от String#bytesize:

'foo'.bytesize        # => 3
'тест'.bytesize       # => 8
'こんにちは'.bytesize   # => 15

String#size — это псевдоним для String#length.

Также алиас: size
lines(Line_sep = $/, chomp: false) → массив строк Показать исходный код
static VALUE
rb_str_lines(int argc, VALUE *argv, VALUE str)
{
    VALUE ary = WANTARRAY("lines", 0);
    return rb_str_enumerate_lines(argc, argv, str, ary);
}

Формирует подстроки («строки») self в соответствии с заданными аргументами (см. String#each_line для подробностей); возвращает строки в массиве.

ljust(size, pad_string = ' ') → new_string Показать исходный код
static VALUE
rb_str_ljust(int argc, VALUE *argv, VALUE str)
{
    return rb_str_justify(argc, argv, str, 'l');
}

Возвращает левовыровненную копию self.

Если целочисленный аргумент size больше размера (в символах) self, возвращает новую строку длины size, которая является копией self, левовыровненной и дополненной справа символом pad_string:

'hello'.ljust(10)       # => "hello     "
'  hello'.ljust(10)     # => "  hello   "
'hello'.ljust(10, 'ab') # => "helloababa"
'тест'.ljust(10)        # => "тест      "
'こんにちは'.ljust(10)    # => "こんにちは     "

Если size не больше размера self, возвращает копию self:

'hello'.ljust(5)  # => "hello"
'hello'.ljust(1)  # => "hello"

Связанно с: String#rjust, String#center.

lstrip → new_string Показать исходный код
static VALUE
rb_str_lstrip(VALUE str)
{
    char *start;
    long len, loffset;
    RSTRING_GETMEM(str, start, len);
    loffset = lstrip_offset(str, start, start+len, STR_ENC_GET(str));
    if (loffset <= 0) return str_duplicate(rb_cString, str);
    return rb_str_subseq(str, loffset, len - loffset);
}

Возвращает копию self с удалёнными начальными пробелами; см. Пробелы в строках:

whitespace = "\x00\t\n\v\f\r "
s = whitespace + 'abc' + whitespace
s        # => "\u0000\t\n\v\f\r abc\u0000\t\n\v\f\r "
s.lstrip # => "abc\u0000\t\n\v\f\r "

Связанно с: String#rstrip, String#strip.

lstrip! → self или nil Показать исходный код
static VALUE
rb_str_lstrip_bang(VALUE str)
{
    rb_encoding *enc;
    char *start, *s;
    long olen, loffset;

    str_modify_keep_cr(str);
    enc = STR_ENC_GET(str);
    RSTRING_GETMEM(str, start, olen);
    loffset = lstrip_offset(str, start, start+olen, enc);
    if (loffset > 0) {
        long len = olen-loffset;
        s = start + loffset;
        memmove(start, s, len);
        STR_SET_LEN(str, len);
        TERM_FILL(start+len, rb_enc_mbminlen(enc));
        return str;
    }
    return Qnil;
}

Как String#lstrip, за исключением того, что любые изменения производятся в self; возвращает self если изменения внесены, nil в противном случае.

Связанно с: String#rstrip!, String#strip!.

match(pattern, offset = 0) → matchdata or nil Показать исходный код
match(pattern, offset = 0) {|matchdata| ... } → object
static VALUE
rb_str_match_m(int argc, VALUE *argv, VALUE str)
{
    VALUE re, result;
    if (argc < 1)
        rb_check_arity(argc, 1, 2);
    re = argv[0];
    argv[0] = str;
    result = rb_funcallv(get_pat(re), rb_intern("match"), argc, argv);
    if (!NIL_P(result) && rb_block_given_p()) {
        return rb_yield(result);
    }
    return result;
}

Возвращает объект MatchData (или nil) на основе self и заданного pattern.

Примечание: также обновляет специальные глобальные переменные в Regexp.

  • Вычисляет regexp, преобразуя pattern (если это не уже Regexp).

    regexp = Regexp.new(pattern)
    
  • Вычисляет matchdata, который будет объектом MatchData или nil (см. Regexp#match):

    matchdata = <tt>regexp.match(self)

Без блока возвращает вычисленный matchdata:

'foo'.match('f') # => #<MatchData "f">
'foo'.match('o') # => #<MatchData "o">
'foo'.match('x') # => nil

Если целочисленный аргумент offset задан, поиск начинается с индекса offset:

'foo'.match('f', 1) # => nil
'foo'.match('o', 1) # => #<MatchData "o">

С блоком, вызывает блок с вычисленным matchdata и возвращает значение, возвращённое блоком:

'foo'.match(/o/) {|matchdata| matchdata } # => #<MatchData "o">
'foo'.match(/x/) {|matchdata| matchdata } # => nil
'foo'.match(/f/, 1) {|matchdata| matchdata } # => nil
match?(pattern, offset = 0) → true or false Показать исходный код
static VALUE
rb_str_match_m_p(int argc, VALUE *argv, VALUE str)
{
    VALUE re;
    rb_check_arity(argc, 1, 2);
    re = get_pat(argv[0]);
    return rb_reg_match_p(re, str, argc > 1 ? NUM2LONG(argv[1]) : 0);
}

Возвращает true или false в зависимости от того, найдено ли соответствие для self и pattern.

Примечание: не обновляет специальные глобальные переменные в Regexp.

Вычисляет regexp, преобразуя pattern (если это не уже Regexp).

regexp = Regexp.new(pattern)

Возвращает true если self+.match(regexp) возвращает объект MatchData, false в противном случае:

'foo'.match?(/o/) # => true
'foo'.match?('o') # => true
'foo'.match?(/x/) # => false

Если целочисленный аргумент offset задан, поиск начинается с индекса offset:

'foo'.match?('f', 1) # => false
'foo'.match?('o', 1) # => true
next()

Возвращает значение, последующее за self. Последующее значение вычисляется путём инкрементирования символов.

Первый символ, который будет инкрементирован, это самый правый буквенно-цифровой символ или, если таких нет, самый правый символ.

'THX1138'.succ # => "THX1139"
'<<koala>>'.succ # => "<<koalb>>"
'***'.succ # => '**+'

Последующее значение для цифры - другая цифра, происходит "перенос" к следующему слева символу для переполнения с 9 до 0, и добавляется ещё одна цифра при необходимости.

'00'.succ # => "01"
'09'.succ # => "10"
'99'.succ # => "100"

Последующее значение для буквы - другая буква той же формы, происходит "перенос" к следующему слева символу для переполнения, и добавляется ещё одна буква той же формы при необходимости.

'aa'.succ # => "ab"
'az'.succ # => "ba"
'zz'.succ # => "aaa"
'AA'.succ # => "AB"
'AZ'.succ # => "BA"
'ZZ'.succ # => "AAA"

Последующее значение для небуквенно-цифрового символа - следующий символ в порядке сортировки набора символов, происходит "перенос" к следующему слева символу для переполнения, и добавляется ещё один символ при необходимости.

s = 0.chr * 3
s # => "\x00\x00\x00"
s.succ # => "\x00\x00\x01"
s = 255.chr * 3
s # => "\xFF\xFF\xFF"
s.succ # => "\x01\x00\x00\x00"

Перенос может происходить между и среди смесей буквенно-цифровых символов.

s = 'zz99zz99'
s.succ # => "aaa00aa00"
s = '99zz99zz'
s.succ # => "100aa00aa"

Последующее значение для пустой строки - новая пустая строка.

''.succ # => ""

String#next является псевдонимом для String#succ.

Псевдоним для: succ
next!()

Эквивалентно String#succ, но изменяет self на месте; возвращает self.

String#next! является псевдонимом для String#succ!.

Псевдоним для: succ!
oct → integer Показать исходный код
static VALUE
rb_str_oct(VALUE str)
{
    return rb_str_to_inum(str, -8, FALSE);
}

Интерпретирует начальную подстроку self как строку восьмеричных цифр (с необязательным знаком) и возвращает соответствующее число; возвращает ноль, если такой начальной подстроки нет.

'123'.oct             # => 83
'-377'.oct            # => -255
'0377non-numeric'.oct # => 255
'non-numeric'.oct     # => 0

Если self начинается с 0, индикаторы радикса учитываются; см. Kernel#Integer.

Связанные: String#hex.

ord → integer Показать исходный код
static VALUE
rb_str_ord(VALUE s)
{
    unsigned int c;

    c = rb_enc_codepoint(RSTRING_PTR(s), RSTRING_END(s), STR_ENC_GET(s));
    return UINT2NUM(c);
}

Возвращает целое значение порядкового номера первого символа self:

'h'.ord         # => 104
'hello'.ord     # => 104
'тест'.ord      # => 1090
'こんにちは'.ord  # => 12371
partition(string_or_regexp) → [head, match, tail] Показать исходный код
static VALUE
rb_str_partition(VALUE str, VALUE sep)
{
    long pos;

    sep = get_pat_quoted(sep, 0);
    if (RB_TYPE_P(sep, T_REGEXP)) {
        if (rb_reg_search(sep, str, 0, 0) < 0) {
            goto failed;
        }
        VALUE match = rb_backref_get();
        struct re_registers *regs = RMATCH_REGS(match);

        pos = BEG(0);
        sep = rb_str_subseq(str, pos, END(0) - pos);
    }
    else {
        pos = rb_str_index(str, sep, 0);
        if (pos < 0) goto failed;
    }
    return rb_ary_new3(3, rb_str_subseq(str, 0, pos),
                          sep,
                          rb_str_subseq(str, pos+RSTRING_LEN(sep),
                                             RSTRING_LEN(str)-pos-RSTRING_LEN(sep)));

  failed:
    return rb_ary_new3(3, str_duplicate(rb_cString, str), str_new_empty_String(str), str_new_empty_String(str));
}

Возвращает массив из 3 элементов подстрок self.

Ищет соответствие шаблона в self, начиная с начала. Шаблон:

  • сам string_or_regexp, если он является Regexp.

  • Regexp.quote(string_or_regexp), если string_or_regexp является строкой.

Если шаблон найден, возвращает часть до совпадения, первую совпавшую часть и часть после совпадения:

'hello'.partition('l')      # => ["he", "l", "lo"]
'hello'.partition('ll')     # => ["he", "ll", "o"]
'hello'.partition('h')      # => ["", "h", "ello"]
'hello'.partition('o')      # => ["hell", "o", ""]
'hello'.partition(/l+/)     #=> ["he", "ll", "o"]
'hello'.partition('')       # => ["", "", "hello"]
'тест'.partition('т')       # => ["", "т", "ест"]
'こんにちは'.partition('に')  # => ["こん", "に", "ちは"]

Если шаблон не найден, возвращает копию self и две пустые строки:

'hello'.partition('x') # => ["hello", "", ""]

Связанные: String#rpartition, String#split.

prepend(*other_strings) → string Показать исходный код
static VALUE
rb_str_prepend_multi(int argc, VALUE *argv, VALUE str)
{
    str_modifiable(str);

    if (argc == 1) {
        rb_str_update(str, 0L, 0L, argv[0]);
    }
    else if (argc > 1) {
        int i;
        VALUE arg_str = rb_str_tmp_new(0);
        rb_enc_copy(arg_str, str);
        for (i = 0; i < argc; i++) {
            rb_str_append(arg_str, argv[i]);
        }
        rb_str_update(str, 0L, 0L, arg_str);
    }

    return str;
}

Добавляет каждую строку из other_strings в начало self и возвращает self:

s = 'foo'
s.prepend('bar', 'baz') # => "barbazfoo"
s                       # => "barbazfoo"

Связанные: String#concat.

replace(other_string) → self

Заменяет содержимое self содержимым other_string:

s = 'foo'        # => "foo"
s.replace('bar') # => "bar"
Псевдоним для: initialize_copy
reverse → string Показать исходный код
static VALUE
rb_str_reverse(VALUE str)
{
    rb_encoding *enc;
    VALUE rev;
    char *s, *e, *p;
    int cr;

    if (RSTRING_LEN(str) <= 1) return str_duplicate(rb_cString, str);
    enc = STR_ENC_GET(str);
    rev = rb_str_new(0, RSTRING_LEN(str));
    s = RSTRING_PTR(str); e = RSTRING_END(str);
    p = RSTRING_END(rev);
    cr = ENC_CODERANGE(str);

    if (RSTRING_LEN(str) > 1) {
        if (single_byte_optimizable(str)) {
            while (s < e) {
                *--p = *s++;
            }
        }
        else if (cr == ENC_CODERANGE_VALID) {
            while (s < e) {
                int clen = rb_enc_fast_mbclen(s, e, enc);

                p -= clen;
                memcpy(p, s, clen);
                s += clen;
            }
        }
        else {
            cr = rb_enc_asciicompat(enc) ?
                ENC_CODERANGE_7BIT : ENC_CODERANGE_VALID;
            while (s < e) {
                int clen = rb_enc_mbclen(s, e, enc);

                if (clen > 1 || (*s & 0x80)) cr = ENC_CODERANGE_UNKNOWN;
                p -= clen;
                memcpy(p, s, clen);
                s += clen;
            }
        }
    }
    STR_SET_LEN(rev, RSTRING_LEN(str));
    str_enc_copy(rev, str);
    ENC_CODERANGE_SET(rev, cr);

    return rev;
}

Возвращает новую строку с символами из self в обратном порядке.

'stressed'.reverse # => "desserts"
reverse! → self Показать исходный код
static VALUE
rb_str_reverse_bang(VALUE str)
{
    if (RSTRING_LEN(str) > 1) {
        if (single_byte_optimizable(str)) {
            char *s, *e, c;

            str_modify_keep_cr(str);
            s = RSTRING_PTR(str);
            e = RSTRING_END(str) - 1;
            while (s < e) {
                c = *s;
                *s++ = *e;
                *e-- = c;
            }
        }
        else {
            str_shared_replace(str, rb_str_reverse(str));
        }
    }
    else {
        str_modify_keep_cr(str);
    }
    return str;
}

Возвращает self с переставленными символами:

s = 'stressed'
s.reverse! # => "desserts"
s          # => "desserts"
rindex(substring, offset = self.length) → integer or nil
rindex(regexp, offset = self.length) → integer or nil
static VALUE
rb_str_rindex_m(int argc, VALUE *argv, VALUE str)
{
    VALUE sub;
    VALUE vpos;
    rb_encoding *enc = STR_ENC_GET(str);
    long pos, len = str_strlen(str, enc); /* str's enc */

    if (rb_scan_args(argc, argv, "11", &sub, &vpos) == 2) {
        pos = NUM2LONG(vpos);
        if (pos < 0) {
            pos += len;
            if (pos < 0) {
                if (RB_TYPE_P(sub, T_REGEXP)) {
                    rb_backref_set(Qnil);
                }
                return Qnil;
            }
        }
        if (pos > len) pos = len;
    }
    else {
        pos = len;
    }

    if (RB_TYPE_P(sub, T_REGEXP)) {
        /* enc = rb_get_check(str, sub); */
        pos = str_offset(RSTRING_PTR(str), RSTRING_END(str), pos,
                         enc, single_byte_optimizable(str));

        if (rb_reg_search(sub, str, pos, 1) >= 0) {
            VALUE match = rb_backref_get();
            struct re_registers *regs = RMATCH_REGS(match);
            pos = rb_str_sublen(str, BEG(0));
            return LONG2NUM(pos);
        }
    }
    else {
        StringValue(sub);
        pos = rb_str_rindex(str, sub, pos);
        if (pos >= 0) return LONG2NUM(pos);
    }
    return Qnil;
}

Возвращает целочисленный индекс последнего вхождения заданной substring, или nil, если не найдено:

'foo'.rindex('f') # => 0
'foo'.rindex('o') # => 2
'foo'.rindex('oo') # => 1
'foo'.rindex('ooo') # => nil

Возвращает целочисленный индекс последнего совпадения с заданным Regexp regexp, или nil, если не найдено:

'foo'.rindex(/f/) # => 0
'foo'.rindex(/o/) # => 2
'foo'.rindex(/oo/) # => 1
'foo'.rindex(/ooo/) # => nil

Последнее совпадение означает начало с возможной последней позиции, а не последней из самых длинных совпадений.

'foo'.rindex(/o+/) # => 2
$~ #=> #<MatchData "o">

Чтобы получить последнее самое длинное совпадение, нужно объединить с отрицательным lookbehind.

'foo'.rindex(/(?<!o)o+/) # => 1
$~ #=> #<MatchData "oo">

Или String#index с отрицательным lookforward.

'foo'.index(/o+(?!.*o)/) # => 1
$~ #=> #<MatchData "oo">

Целочисленный аргумент offset, если задан и неотрицателен, определяет максимальную стартовую позицию в

string to _end_ the search:

 'foo'.rindex('o', 0) # => nil
 'foo'.rindex('o', 1) # => 1
 'foo'.rindex('o', 2) # => 2
 'foo'.rindex('o', 3) # => 2

Если offset является отрицательным целым числом, максимальная стартовая позиция в строке для завершения поиска — это сумма длины строки и offset:

'foo'.rindex('o', -1) # => 2
'foo'.rindex('o', -2) # => 1
'foo'.rindex('o', -3) # => nil
'foo'.rindex('o', -4) # => nil

Связанные: String#index.

rjust(size, pad_string = ' ') → new_string Show source
static VALUE
rb_str_rjust(int argc, VALUE *argv, VALUE str)
{
    return rb_str_justify(argc, argv, str, 'r');
}

Возвращает выровненную по правому краю копию self.

Если целочисленный аргумент size больше размера (в символах) self, возвращает новую строку длиной size, которая является копией self, выровненной по правому краю и дополненной слева pad_string:

'hello'.rjust(10)       # => "     hello"
'hello  '.rjust(10)     # => "   hello  "
'hello'.rjust(10, 'ab') # => "ababahello"
'тест'.rjust(10)        # => "      тест"
'こんにちは'.rjust(10)    # => "     こんにちは"

Если size не больше размера self, возвращает копию self:

'hello'.rjust(5, 'ab')  # => "hello"
'hello'.rjust(1, 'ab')  # => "hello"

Связанные: String#ljust, String#center.

rpartition(sep) → [head, match, tail] Show source
static VALUE
rb_str_rpartition(VALUE str, VALUE sep)
{
    long pos = RSTRING_LEN(str);

    sep = get_pat_quoted(sep, 0);
    if (RB_TYPE_P(sep, T_REGEXP)) {
        if (rb_reg_search(sep, str, pos, 1) < 0) {
            goto failed;
        }
        VALUE match = rb_backref_get();
        struct re_registers *regs = RMATCH_REGS(match);

        pos = BEG(0);
        sep = rb_str_subseq(str, pos, END(0) - pos);
    }
    else {
        pos = rb_str_sublen(str, pos);
        pos = rb_str_rindex(str, sep, pos);
        if (pos < 0) {
            goto failed;
        }
        pos = rb_str_offset(str, pos);
    }

    return rb_ary_new3(3, rb_str_subseq(str, 0, pos),
                          sep,
                          rb_str_subseq(str, pos+RSTRING_LEN(sep),
                                        RSTRING_LEN(str)-pos-RSTRING_LEN(sep)));
  failed:
    return rb_ary_new3(3, str_new_empty_String(str), str_new_empty_String(str), str_duplicate(rb_cString, str));
}

Возвращает 3-элементный массив подстрок self.

Сопоставляет шаблон с self, просматривая с конца. Шаблон:

  • string_or_regexp сам по себе, если он является Regexp.

  • Regexp.quote(string_or_regexp), если string_or_regexp является строкой.

Если шаблон найден, возвращает префикс, последнее совпадение, суффикс:

'hello'.rpartition('l')      # => ["hel", "l", "o"]
'hello'.rpartition('ll')     # => ["he", "ll", "o"]
'hello'.rpartition('h')      # => ["", "h", "ello"]
'hello'.rpartition('o')      # => ["hell", "o", ""]
'hello'.rpartition(/l+/)     # => ["hel", "l", "o"]
'hello'.rpartition('')       # => ["hello", "", ""]
'тест'.rpartition('т')       # => ["тес", "т", ""]
'こんにちは'.rpartition('に')  # => ["こん", "に", "ちは"]

Если шаблон не найден, возвращает две пустые строки и копию self:

'hello'.rpartition('x') # => ["", "", "hello"]

Связанные: String#partition, String#split.

rstrip → new_string Show source
static VALUE
rb_str_rstrip(VALUE str)
{
    rb_encoding *enc;
    char *start;
    long olen, roffset;

    enc = STR_ENC_GET(str);
    RSTRING_GETMEM(str, start, olen);
    roffset = rstrip_offset(str, start, start+olen, enc);

    if (roffset <= 0) return str_duplicate(rb_cString, str);
    return rb_str_subseq(str, 0, olen-roffset);
}

Возвращает копию получателя с удаленными завершающими пробелами; см. Пробельные символы в строках:

whitespace = "\x00\t\n\v\f\r "
s = whitespace + 'abc' + whitespace
s        # => "\u0000\t\n\v\f\r abc\u0000\t\n\v\f\r "
s.rstrip # => "\u0000\t\n\v\f\r abc"

Связанные: String#lstrip, String#strip.

rstrip! → self or nil Show source
static VALUE
rb_str_rstrip_bang(VALUE str)
{
    rb_encoding *enc;
    char *start;
    long olen, roffset;

    str_modify_keep_cr(str);
    enc = STR_ENC_GET(str);
    RSTRING_GETMEM(str, start, olen);
    roffset = rstrip_offset(str, start, start+olen, enc);
    if (roffset > 0) {
        long len = olen - roffset;

        STR_SET_LEN(str, len);
        TERM_FILL(start+len, rb_enc_mbminlen(enc));
        return str;
    }
    return Qnil;
}

Как String#rstrip, за исключением того, что любые изменения вносятся в self; возвращает self, если были внесены какие-либо изменения, nil в противном случае.

Связанные: String#lstrip!, String#strip!.

scan(string_or_regexp) → array Show source
scan(string_or_regexp) {|matches| ... } → self
static VALUE
rb_str_scan(VALUE str, VALUE pat)
{
    VALUE result;
    long start = 0;
    long last = -1, prev = 0;
    char *p = RSTRING_PTR(str); long len = RSTRING_LEN(str);

    pat = get_pat_quoted(pat, 1);
    mustnot_broken(str);
    if (!rb_block_given_p()) {
        VALUE ary = rb_ary_new();

        while (!NIL_P(result = scan_once(str, pat, &start, 0))) {
            last = prev;
            prev = start;
            rb_ary_push(ary, result);
        }
        if (last >= 0) rb_pat_search(pat, str, last, 1);
        else rb_backref_set(Qnil);
        return ary;
    }

    while (!NIL_P(result = scan_once(str, pat, &start, 1))) {
        last = prev;
        prev = start;
        rb_yield(result);
        str_mod_check(str, p, len);
    }
    if (last >= 0) rb_pat_search(pat, str, last, 1);
    return str;
}

Сопоставляет шаблон с self; шаблон:

  • string_or_regexp сам по себе, если он является Regexp.

  • Regexp.quote(string_or_regexp), если string_or_regexp является строкой.

Перебирает self, создавая коллекцию результатов сопоставления:

  • Если шаблон не содержит групп, каждый результат — это найденная строка, $&.

  • Если шаблон содержит группы, каждый результат — это массив, содержащий по одной записи на группу.

Без блока возвращает массив результатов:

s = 'cruel world'
s.scan(/\w+/)      # => ["cruel", "world"]
s.scan(/.../)      # => ["cru", "el ", "wor"]
s.scan(/(...)/)    # => [["cru"], ["el "], ["wor"]]
s.scan(/(..)(..)/) # => [["cr", "ue"], ["l ", "wo"]]

С блоком вызывает блок с каждым результатом; возвращает self:

s.scan(/\w+/) {|w| print "<<#{w}>> " }
print "\n"
s.scan(/(.)(.)/) {|x,y| print y, x }
print "\n"

Вывод:

<<cruel>> <<world>>
rceu lowlr
scrub(replacement_string = default_replacement) → new_string Show source
scrub{|bytes| ... } → new_string
static VALUE
str_scrub(int argc, VALUE *argv, VALUE str)
{
    VALUE repl = argc ? (rb_check_arity(argc, 0, 1), argv[0]) : Qnil;
    VALUE new = rb_str_scrub(str, repl);
    return NIL_P(new) ? str_duplicate(rb_cString, str): new;
}

Возвращает копию self с каждой неверной байтовой последовательностью, заменённой на заданную replacement_string.

Без блока и без аргумента заменяет каждую неверную последовательность на строку замены по умолчанию ("�" для кодировки Unicode, '?' в противном случае):

s = "foo\x81\x81bar"
s.scrub # => "foo��bar"

Без блока и с аргументом replacement_string, заменяет каждую неверную последовательность на эту строку:

"foo\x81\x81bar".scrub('xyzzy') # => "fooxyzzyxyzzybar"

С блоком заменяет каждую неверную последовательность на значение блока:

"foo\x81\x81bar".scrub {|bytes| p bytes; 'XYZZY' }
# => "fooXYZZYXYZZYbar"

Вывод:

"\x81"
"\x81"
scrub! → self Show source
scrub!(replacement_string = default_replacement) → self
scrub!{|bytes| ... } → self
static VALUE
str_scrub_bang(int argc, VALUE *argv, VALUE str)
{
    VALUE repl = argc ? (rb_check_arity(argc, 0, 1), argv[0]) : Qnil;
    VALUE new = rb_str_scrub(str, repl);
    if (!NIL_P(new)) rb_str_replace(str, new);
    return str;
}

Как String#scrub, за исключением того, что любые замены вносятся в self.

setbyte(index, integer) → integer Show source
static VALUE
rb_str_setbyte(VALUE str, VALUE index, VALUE value)
{
    long pos = NUM2LONG(index);
    long len = RSTRING_LEN(str);
    char *ptr, *head, *left = 0;
    rb_encoding *enc;
    int cr = ENC_CODERANGE_UNKNOWN, width, nlen;

    if (pos < -len || len <= pos)
        rb_raise(rb_eIndexError, "index %ld out of string", pos);
    if (pos < 0)
        pos += len;

    VALUE v = rb_to_int(value);
    VALUE w = rb_int_and(v, INT2FIX(0xff));
    char byte = (char)(NUM2INT(w) & 0xFF);

    if (!str_independent(str))
        str_make_independent(str);
    enc = STR_ENC_GET(str);
    head = RSTRING_PTR(str);
    ptr = &head[pos];
    if (!STR_EMBED_P(str)) {
        cr = ENC_CODERANGE(str);
        switch (cr) {
          case ENC_CODERANGE_7BIT:
            left = ptr;
            *ptr = byte;
            if (ISASCII(byte)) goto end;
            nlen = rb_enc_precise_mbclen(left, head+len, enc);
            if (!MBCLEN_CHARFOUND_P(nlen))
                ENC_CODERANGE_SET(str, ENC_CODERANGE_BROKEN);
            else
                ENC_CODERANGE_SET(str, ENC_CODERANGE_VALID);
            goto end;
          case ENC_CODERANGE_VALID:
            left = rb_enc_left_char_head(head, ptr, head+len, enc);
            width = rb_enc_precise_mbclen(left, head+len, enc);
            *ptr = byte;
            nlen = rb_enc_precise_mbclen(left, head+len, enc);
            if (!MBCLEN_CHARFOUND_P(nlen))
                ENC_CODERANGE_SET(str, ENC_CODERANGE_BROKEN);
            else if (MBCLEN_CHARFOUND_LEN(nlen) != width || ISASCII(byte))
                ENC_CODERANGE_CLEAR(str);
            goto end;
        }
    }
    ENC_CODERANGE_CLEAR(str);
    *ptr = byte;

  end:
    return value;
}

Устанавливает байт по нулевому индексу index в integer; возвращает integer:

s = 'abcde'      # => "abcde"
s.setbyte(0, 98) # => 98
s                # => "bbcde"

Связанные: String#getbyte.

shellescape → string Show source
# File lib/shellwords.rb, line 224
def shellescape
  Shellwords.escape(self)
end

Экранирует str, чтобы его можно было безопасно использовать в командной строке Bourne shell.

См. Shellwords.shellescape для подробностей.

shellsplit → array Show source
# File lib/shellwords.rb, line 213
def shellsplit
  Shellwords.split(self)
end

Разделяет str на массив токенов так же, как это делает оболочка UNIX Bourne.

См. Shellwords.shellsplit для подробностей.

size()

Возвращает количество символов (не байтов) в self:

'foo'.length        # => 3
'тест'.length       # => 4
'こんにちは'.length   # => 5

В отличие от String#bytesize:

'foo'.bytesize        # => 3
'тест'.bytesize       # => 8
'こんにちは'.bytesize   # => 15

String#size является псевдонимом для String#length.

Псевдоним для: length
slice(*args)

Возвращает подстроку self, указанную аргументами. См. примеры в Срезы строк.

Псевдоним для: []
slice!(index) → new_string or nil Show source
slice!(start, length) → new_string or nil
slice!(range) → new_string or nil
slice!(regexp, capture = 0) → new_string or nil
slice!(substring) → new_string or nil
static VALUE
rb_str_slice_bang(int argc, VALUE *argv, VALUE str)
{
    VALUE result = Qnil;
    VALUE indx;
    long beg, len = 1;
    char *p;

    rb_check_arity(argc, 1, 2);
    str_modify_keep_cr(str);
    indx = argv[0];
    if (RB_TYPE_P(indx, T_REGEXP)) {
        if (rb_reg_search(indx, str, 0, 0) < 0) return Qnil;
        VALUE match = rb_backref_get();
        struct re_registers *regs = RMATCH_REGS(match);
        int nth = 0;
        if (argc > 1 && (nth = rb_reg_backref_number(match, argv[1])) < 0) {
            if ((nth += regs->num_regs) <= 0) return Qnil;
        }
        else if (nth >= regs->num_regs) return Qnil;
        beg = BEG(nth);
        len = END(nth) - beg;
        goto subseq;
    }
    else if (argc == 2) {
        beg = NUM2LONG(indx);
        len = NUM2LONG(argv[1]);
        goto num_index;
    }
    else if (FIXNUM_P(indx)) {
        beg = FIX2LONG(indx);
        if (!(p = rb_str_subpos(str, beg, &len))) return Qnil;
        if (!len) return Qnil;
        beg = p - RSTRING_PTR(str);
        goto subseq;
    }
    else if (RB_TYPE_P(indx, T_STRING)) {
        beg = rb_str_index(str, indx, 0);
        if (beg == -1) return Qnil;
        len = RSTRING_LEN(indx);
        result = str_duplicate(rb_cString, indx);
        goto squash;
    }
    else {
        switch (rb_range_beg_len(indx, &beg, &len, str_strlen(str, NULL), 0)) {
          case Qnil:
            return Qnil;
          case Qfalse:
            beg = NUM2LONG(indx);
            if (!(p = rb_str_subpos(str, beg, &len))) return Qnil;
            if (!len) return Qnil;
            beg = p - RSTRING_PTR(str);
            goto subseq;
          default:
            goto num_index;
        }
    }

  num_index:
    if (!(p = rb_str_subpos(str, beg, &len))) return Qnil;
    beg = p - RSTRING_PTR(str);

  subseq:
    result = rb_str_new(RSTRING_PTR(str)+beg, len);
    rb_enc_cr_str_copy_for_substr(result, str);

  squash:
    if (len > 0) {
        if (beg == 0) {
            rb_str_drop_bytes(str, len);
        }
        else {
            char *sptr = RSTRING_PTR(str);
            long slen = RSTRING_LEN(str);
            if (beg + len > slen) /* pathological check */
                len = slen - beg;
            memmove(sptr + beg,
                    sptr + beg + len,
                    slen - (beg + len));
            slen -= len;
            STR_SET_LEN(str, slen);
            TERM_FILL(&sptr[slen], TERM_LEN(str));
        }
    }
    return result;
}

Удаляет и возвращает подстроку self, указанную аргументами. См. Срезы строк.

Несколько примеров:

string = "This is a string"
string.slice!(2)        #=> "i"
string.slice!(3..6)     #=> " is "
string.slice!(/s.*t/)   #=> "sa st"
string.slice!("r")      #=> "r"
string                  #=> "Thing"
split(field_sep = $;, limit = nil) → array Показать исходный код
split(field_sep = $;, limit = nil) {|substring| ... } → self
static VALUE
rb_str_split_m(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    VALUE spat;
    VALUE limit;
    split_type_t split_type;
    long beg, end, i = 0, empty_count = -1;
    int lim = 0;
    VALUE result, tmp;

    result = rb_block_given_p() ? Qfalse : Qnil;
    if (rb_scan_args(argc, argv, "02", &spat, &limit) == 2) {
        lim = NUM2INT(limit);
        if (lim <= 0) limit = Qnil;
        else if (lim == 1) {
            if (RSTRING_LEN(str) == 0)
                return result ? rb_ary_new2(0) : str;
            tmp = str_duplicate(rb_cString, str);
            if (!result) {
                rb_yield(tmp);
                return str;
            }
            return rb_ary_new3(1, tmp);
        }
        i = 1;
    }
    if (NIL_P(limit) && !lim) empty_count = 0;

    enc = STR_ENC_GET(str);
    split_type = SPLIT_TYPE_REGEXP;
    if (!NIL_P(spat)) {
        spat = get_pat_quoted(spat, 0);
    }
    else if (NIL_P(spat = rb_fs)) {
        split_type = SPLIT_TYPE_AWK;
    }
    else if (!(spat = rb_fs_check(spat))) {
        rb_raise(rb_eTypeError, "value of $; must be String or Regexp");
    }
    else {
        rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "$; is set to non-nil value");
    }
    if (split_type != SPLIT_TYPE_AWK) {
        switch (BUILTIN_TYPE(spat)) {
          case T_REGEXP:
            rb_reg_options(spat); /* check if uninitialized */
            tmp = RREGEXP_SRC(spat);
            split_type = literal_split_pattern(tmp, SPLIT_TYPE_REGEXP);
            if (split_type == SPLIT_TYPE_AWK) {
                spat = tmp;
                split_type = SPLIT_TYPE_STRING;
            }
            break;

          case T_STRING:
            mustnot_broken(spat);
            split_type = literal_split_pattern(spat, SPLIT_TYPE_STRING);
            break;

          default:
            UNREACHABLE_RETURN(Qnil);
        }
    }

#define SPLIT_STR(beg, len) (empty_count = split_string(result, str, beg, len, empty_count))

    if (result) result = rb_ary_new();
    beg = 0;
    char *ptr = RSTRING_PTR(str);
    char *eptr = RSTRING_END(str);
    if (split_type == SPLIT_TYPE_AWK) {
        char *bptr = ptr;
        int skip = 1;
        unsigned int c;

        end = beg;
        if (is_ascii_string(str)) {
            while (ptr < eptr) {
                c = (unsigned char)*ptr++;
                if (skip) {
                    if (ascii_isspace(c)) {
                        beg = ptr - bptr;
                    }
                    else {
                        end = ptr - bptr;
                        skip = 0;
                        if (!NIL_P(limit) && lim <= i) break;
                    }
                }
                else if (ascii_isspace(c)) {
                    SPLIT_STR(beg, end-beg);
                    skip = 1;
                    beg = ptr - bptr;
                    if (!NIL_P(limit)) ++i;
                }
                else {
                    end = ptr - bptr;
                }
            }
        }
        else {
            while (ptr < eptr) {
                int n;

                c = rb_enc_codepoint_len(ptr, eptr, &n, enc);
                ptr += n;
                if (skip) {
                    if (rb_isspace(c)) {
                        beg = ptr - bptr;
                    }
                    else {
                        end = ptr - bptr;
                        skip = 0;
                        if (!NIL_P(limit) && lim <= i) break;
                    }
                }
                else if (rb_isspace(c)) {
                    SPLIT_STR(beg, end-beg);
                    skip = 1;
                    beg = ptr - bptr;
                    if (!NIL_P(limit)) ++i;
                }
                else {
                    end = ptr - bptr;
                }
            }
        }
    }
    else if (split_type == SPLIT_TYPE_STRING) {
        char *str_start = ptr;
        char *substr_start = ptr;
        char *sptr = RSTRING_PTR(spat);
        long slen = RSTRING_LEN(spat);

        mustnot_broken(str);
        enc = rb_enc_check(str, spat);
        while (ptr < eptr &&
               (end = rb_memsearch(sptr, slen, ptr, eptr - ptr, enc)) >= 0) {
            /* Check we are at the start of a char */
            char *t = rb_enc_right_char_head(ptr, ptr + end, eptr, enc);
            if (t != ptr + end) {
                ptr = t;
                continue;
            }
            SPLIT_STR(substr_start - str_start, (ptr+end) - substr_start);
            ptr += end + slen;
            substr_start = ptr;
            if (!NIL_P(limit) && lim <= ++i) break;
        }
        beg = ptr - str_start;
    }
    else if (split_type == SPLIT_TYPE_CHARS) {
        char *str_start = ptr;
        int n;

        mustnot_broken(str);
        enc = rb_enc_get(str);
        while (ptr < eptr &&
               (n = rb_enc_precise_mbclen(ptr, eptr, enc)) > 0) {
            SPLIT_STR(ptr - str_start, n);
            ptr += n;
            if (!NIL_P(limit) && lim <= ++i) break;
        }
        beg = ptr - str_start;
    }
    else {
        long len = RSTRING_LEN(str);
        long start = beg;
        long idx;
        int last_null = 0;
        struct re_registers *regs;
        VALUE match = 0;

        for (; rb_reg_search(spat, str, start, 0) >= 0;
             (match ? (rb_match_unbusy(match), rb_backref_set(match)) : (void)0)) {
            match = rb_backref_get();
            if (!result) rb_match_busy(match);
            regs = RMATCH_REGS(match);
            end = BEG(0);
            if (start == end && BEG(0) == END(0)) {
                if (!ptr) {
                    SPLIT_STR(0, 0);
                    break;
                }
                else if (last_null == 1) {
                    SPLIT_STR(beg, rb_enc_fast_mbclen(ptr+beg, eptr, enc));
                    beg = start;
                }
                else {
                    if (start == len)
                        start++;
                    else
                        start += rb_enc_fast_mbclen(ptr+start,eptr,enc);
                    last_null = 1;
                    continue;
                }
            }
            else {
                SPLIT_STR(beg, end-beg);
                beg = start = END(0);
            }
            last_null = 0;

            for (idx=1; idx < regs->num_regs; idx++) {
                if (BEG(idx) == -1) continue;
                SPLIT_STR(BEG(idx), END(idx)-BEG(idx));
            }
            if (!NIL_P(limit) && lim <= ++i) break;
        }
        if (match) rb_match_unbusy(match);
    }
    if (RSTRING_LEN(str) > 0 && (!NIL_P(limit) || RSTRING_LEN(str) > beg || lim < 0)) {
        SPLIT_STR(beg, RSTRING_LEN(str)-beg);
    }

    return result ? result : str;
}

Возвращает массив подстрок self, полученных путём разделения self по каждой встрече заданного разделителя поля field_sep.

Если field_sep равно $;:

  • Если $; равно nil (его значение по умолчанию), разделение происходит так, как если бы field_sep было задано как пробельный символ (см. ниже).

  • Если $; является строкой, разделение происходит так, как если бы field_sep было задано как эта строка (см. ниже).

Если field_sep равно ' ' и limit равно nil:

'abc def ghi'.split(' ')         => ["abc", "def", "ghi"]
"abc \n\tdef\t\n  ghi".split(' ') # => ["abc", "def", "ghi"]
'abc  def   ghi'.split(' ')      => ["abc", "def", "ghi"]
''.split(' ')                    => []

Если field_sep — строка, отличная от ' ' и limit равно nil:

'abracadabra'.split('ab')  => ["", "racad", "ra"]
'aaabcdaaa'.split('a')     => ["", "", "", "bcd"]
''.split('a')              => []
'3.14159'.split('1')       => ["3.", "4", "59"]
'!@#$%^$&*($)_+'.split('$') # => ["!@#", "%^", "&*(", ")_+"]
'тест'.split('т')          => ["", "ес"]
'こんにちは'.split('に')     => ["こん", "ちは"]

Если field_sep — Regexp и limit равно nil:

'abracadabra'.split(/ab/) # => ["", "racad", "ra"]
'aaabcdaaa'.split(/a/)   => ["", "", "", "bcd"]
'aaabcdaaa'.split(//)    => ["a", "a", "a", "b", "c", "d", "a", "a", "a"]
'1 + 1 == 2'.split(/\W+/) # => ["1", "1", "2"]

Если регулярное выражение содержит группы, их совпадения также включаются в возвращаемый массив:

'1:2:3'.split(/(:)()()/, 2) # => ["1", ":", "", "", "2:3"]

Как показано выше, если limit равно nil , пустые хвостовые подстроки не возвращаются; то же верно, если limit равно нулю:

'aaabcdaaa'.split('a')   => ["", "", "", "bcd"]
'aaabcdaaa'.split('a', 0) # => ["", "", "", "bcd"]

Если limit — положительное целое число n , не более n - 1- разделений, так что возвращается не более n подстрок, и хвостовые пустые подстроки включаются:

'aaabcdaaa'.split('a', 1) # => ["aaabcdaaa"]
'aaabcdaaa'.split('a', 2) # => ["", "aabcdaaa"]
'aaabcdaaa'.split('a', 5) # => ["", "", "", "bcd", "aa"]
'aaabcdaaa'.split('a', 7) # => ["", "", "", "bcd", "", "", ""]
'aaabcdaaa'.split('a', 8) # => ["", "", "", "bcd", "", "", ""]

Обратите внимание, что если field_sep является регулярным выражением, содержащим группы, их совпадения находятся в возвращаемом массиве, но не учитываются при подсчёте лимита.

Если limit отрицательно, оно ведет себя так же, как если бы limit было nil , что означает, что нет ограничений, и хвостовые пустые подстроки включаются:

'aaabcdaaa'.split('a', -1) # => ["", "", "", "bcd", "", "", ""]

Если блок задан, он вызывается с каждой подстрокой:

'abc def ghi'.split(' ') {|substring| p substring }

Вывод:

"abc"
"def"
"ghi"

Связанные: String#partition, String#rpartition.

squeeze(*selectors) → new_string Показать исходный код
static VALUE
rb_str_squeeze(int argc, VALUE *argv, VALUE str)
{
    str = str_duplicate(rb_cString, str);
    rb_str_squeeze_bang(argc, argv, str);
    return str;
}

Возвращает копию self с символами, указанными в selectors «сжатыми» (см. Множественные селекторы символов):

«Сжатие» означает, что каждая последовательность выбранных символов сжимается до одного символа; без аргументов происходит сжатие всех символов:

"yellow moon".squeeze                  #=> "yelow mon"
"  now   is  the".squeeze(" ")         #=> " now is the"
"putters shoot balls".squeeze("m-z")   #=> "puters shot balls"
squeeze!(*selectors) → self or nil Показать исходный код
static VALUE
rb_str_squeeze_bang(int argc, VALUE *argv, VALUE str)
{
    char squeez[TR_TABLE_SIZE];
    rb_encoding *enc = 0;
    VALUE del = 0, nodel = 0;
    unsigned char *s, *send, *t;
    int i, modify = 0;
    int ascompat, singlebyte = single_byte_optimizable(str);
    unsigned int save;

    if (argc == 0) {
        enc = STR_ENC_GET(str);
    }
    else {
        for (i=0; i<argc; i++) {
            VALUE s = argv[i];

            StringValue(s);
            enc = rb_enc_check(str, s);
            if (singlebyte && !single_byte_optimizable(s))
                singlebyte = 0;
            tr_setup_table(s, squeez, i==0, &del, &nodel, enc);
        }
    }

    str_modify_keep_cr(str);
    s = t = (unsigned char *)RSTRING_PTR(str);
    if (!s || RSTRING_LEN(str) == 0) return Qnil;
    send = (unsigned char *)RSTRING_END(str);
    save = -1;
    ascompat = rb_enc_asciicompat(enc);

    if (singlebyte) {
        while (s < send) {
            unsigned int c = *s++;
            if (c != save || (argc > 0 && !squeez[c])) {
                *t++ = save = c;
            }
        }
    }
    else {
        while (s < send) {
            unsigned int c;
            int clen;

            if (ascompat && (c = *s) < 0x80) {
                if (c != save || (argc > 0 && !squeez[c])) {
                    *t++ = save = c;
                }
                s++;
            }
            else {
                c = rb_enc_codepoint_len((char *)s, (char *)send, &clen, enc);

                if (c != save || (argc > 0 && !tr_find(c, squeez, del, nodel))) {
                    if (t != s) rb_enc_mbcput(c, t, enc);
                    save = c;
                    t += clen;
                }
                s += clen;
            }
        }
    }

    TERM_FILL((char *)t, TERM_LEN(str));
    if ((char *)t - RSTRING_PTR(str) != RSTRING_LEN(str)) {
        STR_SET_LEN(str, (char *)t - RSTRING_PTR(str));
        modify = 1;
    }

    if (modify) return str;
    return Qnil;
}

Подобно String#squeeze, но изменяет self на месте. Возвращает self , если были внесены какие-либо изменения, nil в противном случае.

start_with?(*string_or_regexp) → true or false Показать исходный код
static VALUE
rb_str_start_with(int argc, VALUE *argv, VALUE str)
{
    int i;

    for (i=0; i<argc; i++) {
        VALUE tmp = argv[i];
        if (RB_TYPE_P(tmp, T_REGEXP)) {
            if (rb_reg_start_with_p(tmp, str))
                return Qtrue;
        }
        else {
            StringValue(tmp);
            rb_enc_check(str, tmp);
            if (RSTRING_LEN(str) < RSTRING_LEN(tmp)) continue;
            if (memcmp(RSTRING_PTR(str), RSTRING_PTR(tmp), RSTRING_LEN(tmp)) == 0)
                return Qtrue;
        }
    }
    return Qfalse;
}

Возвращает значение, указывающее, начинается ли self с любого из заданных string_or_regexp.

Сопоставляет шаблоны с началом self. Для каждого заданного string_or_regexp, шаблон:

  • сам string_or_regexp , если это Regexp.

  • Regexp.quote(string_or_regexp) , если string_or_regexp — это строка.

Возвращает true , если какой-либо шаблон соответствует началу, false в противном случае:

'hello'.start_with?('hell')               # => true
'hello'.start_with?(/H/i)                 # => true
'hello'.start_with?('heaven', 'hell')     # => true
'hello'.start_with?('heaven', 'paradise') # => false
'тест'.start_with?('т')                   # => true
'こんにちは'.start_with?('こ')              # => true

Связанные: String#end_with?.

strip → new_string Показать исходный код
static VALUE
rb_str_strip(VALUE str)
{
    char *start;
    long olen, loffset, roffset;
    rb_encoding *enc = STR_ENC_GET(str);

    RSTRING_GETMEM(str, start, olen);
    loffset = lstrip_offset(str, start, start+olen, enc);
    roffset = rstrip_offset(str, start+loffset, start+olen, enc);

    if (loffset <= 0 && roffset <= 0) return str_duplicate(rb_cString, str);
    return rb_str_subseq(str, loffset, olen-loffset-roffset);
}

Возвращает копию получателя со удалёнными начальными и конечными пробелами; см. Пробелы в строках:

whitespace = "\x00\t\n\v\f\r "
s = whitespace + 'abc' + whitespace
s       # => "\u0000\t\n\v\f\r abc\u0000\t\n\v\f\r "
s.strip # => "abc"

Связанные: String#lstrip, String#rstrip.

strip! → self or nil Показать исходный код
static VALUE
rb_str_strip_bang(VALUE str)
{
    char *start;
    long olen, loffset, roffset;
    rb_encoding *enc;

    str_modify_keep_cr(str);
    enc = STR_ENC_GET(str);
    RSTRING_GETMEM(str, start, olen);
    loffset = lstrip_offset(str, start, start+olen, enc);
    roffset = rstrip_offset(str, start+loffset, start+olen, enc);

    if (loffset > 0 || roffset > 0) {
        long len = olen-roffset;
        if (loffset > 0) {
            len -= loffset;
            memmove(start, start + loffset, len);
        }
        STR_SET_LEN(str, len);
        TERM_FILL(start+len, rb_enc_mbminlen(enc));
        return str;
    }
    return Qnil;
}

Подобно String#strip, за исключением того, что любые изменения выполняются на месте; возвращает self , если были внесены какие-либо изменения, nil в противном случае.

Связанные: String#lstrip!, String#strip!.

sub(pattern, replacement) → new_string Показать исходный код
sub(pattern) {|match| ... } → new_string
static VALUE
rb_str_sub(int argc, VALUE *argv, VALUE str)
{
    str = str_duplicate(rb_cString, str);
    rb_str_sub_bang(argc, argv, str);
    return str;
}

Возвращает копию self с заменой только первого вхождения (не всех вхождений) заданного pattern.

См. Методы подстановки.

Связанные: String#sub!, String#gsub, String#gsub!.

sub!(pattern, replacement) → self or nil Показать исходный код
sub!(pattern) {|match| ... } → self or nil
static VALUE
rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
{
    VALUE pat, repl, hash = Qnil;
    int iter = 0;
    long plen;
    int min_arity = rb_block_given_p() ? 1 : 2;
    long beg;

    rb_check_arity(argc, min_arity, 2);
    if (argc == 1) {
        iter = 1;
    }
    else {
        repl = argv[1];
        hash = rb_check_hash_type(argv[1]);
        if (NIL_P(hash)) {
            StringValue(repl);
        }
    }

    pat = get_pat_quoted(argv[0], 1);

    str_modifiable(str);
    beg = rb_pat_search(pat, str, 0, 1);
    if (beg >= 0) {
        rb_encoding *enc;
        int cr = ENC_CODERANGE(str);
        long beg0, end0;
        VALUE match, match0 = Qnil;
        struct re_registers *regs;
        char *p, *rp;
        long len, rlen;

        match = rb_backref_get();
        regs = RMATCH_REGS(match);
        if (RB_TYPE_P(pat, T_STRING)) {
            beg0 = beg;
            end0 = beg0 + RSTRING_LEN(pat);
            match0 = pat;
        }
        else {
            beg0 = BEG(0);
            end0 = END(0);
            if (iter) match0 = rb_reg_nth_match(0, match);
        }

        if (iter || !NIL_P(hash)) {
            p = RSTRING_PTR(str); len = RSTRING_LEN(str);

            if (iter) {
                repl = rb_obj_as_string(rb_yield(match0));
            }
            else {
                repl = rb_hash_aref(hash, rb_str_subseq(str, beg0, end0 - beg0));
                repl = rb_obj_as_string(repl);
            }
            str_mod_check(str, p, len);
            rb_check_frozen(str);
        }
        else {
            repl = rb_reg_regsub(repl, str, regs, RB_TYPE_P(pat, T_STRING) ? Qnil : pat);
        }

        enc = rb_enc_compatible(str, repl);
        if (!enc) {
            rb_encoding *str_enc = STR_ENC_GET(str);
            p = RSTRING_PTR(str); len = RSTRING_LEN(str);
            if (coderange_scan(p, beg0, str_enc) != ENC_CODERANGE_7BIT ||
                coderange_scan(p+end0, len-end0, str_enc) != ENC_CODERANGE_7BIT) {
                rb_raise(rb_eEncCompatError, "incompatible character encodings: %s and %s",
                         rb_enc_name(str_enc),
                         rb_enc_name(STR_ENC_GET(repl)));
            }
            enc = STR_ENC_GET(repl);
        }
        rb_str_modify(str);
        rb_enc_associate(str, enc);
        if (ENC_CODERANGE_UNKNOWN < cr && cr < ENC_CODERANGE_BROKEN) {
            int cr2 = ENC_CODERANGE(repl);
            if (cr2 == ENC_CODERANGE_BROKEN ||
                (cr == ENC_CODERANGE_VALID && cr2 == ENC_CODERANGE_7BIT))
                cr = ENC_CODERANGE_UNKNOWN;
            else
                cr = cr2;
        }
        plen = end0 - beg0;
        rlen = RSTRING_LEN(repl);
        len = RSTRING_LEN(str);
        if (rlen > plen) {
            RESIZE_CAPA(str, len + rlen - plen);
        }
        p = RSTRING_PTR(str);
        if (rlen != plen) {
            memmove(p + beg0 + rlen, p + beg0 + plen, len - beg0 - plen);
        }
        rp = RSTRING_PTR(repl);
        memmove(p + beg0, rp, rlen);
        len += rlen - plen;
        STR_SET_LEN(str, len);
        TERM_FILL(&RSTRING_PTR(str)[len], TERM_LEN(str));
        ENC_CODERANGE_SET(str, cr);

        return str;
    }
    return Qnil;
}

Возвращает self с заменой только первого вхождения (не всех вхождений) заданного pattern.

См. Методы подстановки.

Связанные: String#sub, String#gsub, String#gsub!.

succ → new_str Показать исходный код
VALUE
rb_str_succ(VALUE orig)
{
    VALUE str;
    str = rb_str_new(RSTRING_PTR(orig), RSTRING_LEN(orig));
    rb_enc_cr_str_copy_for_substr(str, orig);
    return str_succ(str);
}

Возвращает преемника self. Преемник вычисляется путём инкремента символов.

Первый символ, который будет инкрементирован, — это самый правый буквенно-цифровой: или, если нет буквенно-цифровых символов, самый правый символ:

'THX1138'.succ # => "THX1139"
'<<koala>>'.succ # => "<<koalb>>"
'***'.succ # => '**+'

Преемник цифры — другая цифра, «переносящая» в следующий слева символ при переходе от 9 к 0 и добавляющая ещё одну цифру при необходимости:

'00'.succ # => "01"
'09'.succ # => "10"
'99'.succ # => "100"

Преемник буквы — другая буква того же регистра, переносящая в следующий слева символ при переходе, и добавляющая ещё одну букву того же регистра при необходимости:

'aa'.succ # => "ab"
'az'.succ # => "ba"
'zz'.succ # => "aaa"
'AA'.succ # => "AB"
'AZ'.succ # => "BA"
'ZZ'.succ # => "AAA"

Преемник небуквенно-цифрового символа — следующий символ в сортировке кодировок набора символов, переносящий в следующий слева символ при переходе и добавляющий другой символ при необходимости:

s = 0.chr * 3
s # => "\x00\x00\x00"
s.succ # => "\x00\x00\x01"
s = 255.chr * 3
s # => "\xFF\xFF\xFF"
s.succ # => "\x01\x00\x00\x00"

Перенос может происходить между и среди смесей буквенно-цифровых символов:

s = 'zz99zz99'
s.succ # => "aaa00aa00"
s = '99zz99zz'
s.succ # => "100aa00aa"

Преемником пустой строки является новая пустая строка:

''.succ # => ""

String#next — псевдоним для String#succ.

Также алиасируется как: next
succ! → self Показать исходный код
static VALUE
rb_str_succ_bang(VALUE str)
{
    rb_str_modify(str);
    str_succ(str);
    return str;
}

Эквивалентно String#succ, но изменяет self на месте; возвращает self.

String#next! — псевдоним для String#succ!.

Также алиасируется как: next!
sum(n = 16) → целое Показать исходный код
static VALUE
rb_str_sum(int argc, VALUE *argv, VALUE str)
{
    int bits = 16;
    char *ptr, *p, *pend;
    long len;
    VALUE sum = INT2FIX(0);
    unsigned long sum0 = 0;

    if (rb_check_arity(argc, 0, 1) && (bits = NUM2INT(argv[0])) < 0) {
        bits = 0;
    }
    ptr = p = RSTRING_PTR(str);
    len = RSTRING_LEN(str);
    pend = p + len;

    while (p < pend) {
        if (FIXNUM_MAX - UCHAR_MAX < sum0) {
            sum = rb_funcall(sum, '+', 1, LONG2FIX(sum0));
            str_mod_check(str, ptr, len);
            sum0 = 0;
        }
        sum0 += (unsigned char)*p;
        p++;
    }

    if (bits == 0) {
        if (sum0) {
            sum = rb_funcall(sum, '+', 1, LONG2FIX(sum0));
        }
    }
    else {
        if (sum == INT2FIX(0)) {
            if (bits < (int)sizeof(long)*CHAR_BIT) {
                sum0 &= (((unsigned long)1)<<bits)-1;
            }
            sum = LONG2FIX(sum0);
        }
        else {
            VALUE mod;

            if (sum0) {
                sum = rb_funcall(sum, '+', 1, LONG2FIX(sum0));
            }

            mod = rb_funcall(INT2FIX(1), idLTLT, 1, INT2FIX(bits));
            mod = rb_funcall(mod, '-', 1, INT2FIX(1));
            sum = rb_funcall(sum, '&', 1, mod);
        }
    }
    return sum;
}

Возвращает батовую n-битовую контрольную сумму символов в self; контрольная сумма — это сумма двоичных значений каждого байта в self, по модулю 2**n - 1:

'hello'.sum     # => 532
'hello'.sum(4)  # => 4
'hello'.sum(64) # => 532
'тест'.sum      # => 1405
'こんにちは'.sum  # => 2582

Это не очень надёжная контрольная сумма.

swapcase(*options) → строка Показать исходный код
static VALUE
rb_str_swapcase(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    OnigCaseFoldType flags = ONIGENC_CASE_UPCASE | ONIGENC_CASE_DOWNCASE;
    VALUE ret;

    flags = check_case_options(argc, argv, flags);
    enc = str_true_enc(str);
    if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return str_duplicate(rb_cString, str);
    if (flags&ONIGENC_CASE_ASCII_ONLY) {
        ret = rb_str_new(0, RSTRING_LEN(str));
        rb_str_ascii_casemap(str, ret, &flags, enc);
    }
    else {
        ret = rb_str_casemap(str, &flags, enc);
    }
    return ret;
}

Возвращает строку, содержащую символы в self, с изменённым регистром; каждый символ в верхнем регистре заменяется символом в нижнем регистре; каждый символ в нижнем регистре заменяется символом в верхнем регистре:

s = 'Hello World!' # => "Hello World!"
s.swapcase         # => "hELLO wORLD!"

Регистр может быть изменён заданными options; см. Преобразование регистра.

Связанные: String#swapcase!.

swapcase!(*options) → self или nil Показать исходный код
static VALUE
rb_str_swapcase_bang(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    OnigCaseFoldType flags = ONIGENC_CASE_UPCASE | ONIGENC_CASE_DOWNCASE;

    flags = check_case_options(argc, argv, flags);
    str_modify_keep_cr(str);
    enc = str_true_enc(str);
    if (flags&ONIGENC_CASE_ASCII_ONLY)
        rb_str_ascii_casemap(str, str, &flags, enc);
    else
        str_shared_replace(str, rb_str_casemap(str, &flags, enc));

    if (ONIGENC_CASE_MODIFIED&flags) return str;
    return Qnil;
}

Преобразует каждый символ в нижнем регистре в self; преобразует символы в верхнем регистре в нижний; возвращает self если изменения были произведены, nil в противном случае:

s = 'Hello World!' # => "Hello World!"
s.swapcase!        # => "hELLO wORLD!"
s                  # => "hELLO wORLD!"
''.swapcase!       # => nil

Регистр может быть изменён заданными options; см. Преобразование регистра.

Связанные: String#swapcase.

to_c → комплексное Показать исходный код
static VALUE
string_to_c(VALUE self)
{
    char *s;
    VALUE num;

    rb_must_asciicompat(self);

    s = RSTRING_PTR(self);

    if (s && s[RSTRING_LEN(self)]) {
        rb_str_modify(self);
        s = RSTRING_PTR(self);
        s[RSTRING_LEN(self)] = '\0';
    }

    if (!s)
        s = (char *)"";

    (void)parse_comp(s, 0, &num);

    return num;
}

Возвращает комплексное число, представляющее строку. Парсер игнорирует начальные пробелы и хвостовой мусор. Любые числовые последовательности могут быть разделены подчёркиванием. Возвращает ноль для пустой или мусорной строки.

'9'.to_c           #=> (9+0i)
'2.5'.to_c         #=> (2.5+0i)
'2.5/1'.to_c       #=> ((5/2)+0i)
'-3/2'.to_c        #=> ((-3/2)+0i)
'-i'.to_c          #=> (0-1i)
'45i'.to_c         #=> (0+45i)
'3-4i'.to_c        #=> (3-4i)
'-4e2-4e-2i'.to_c  #=> (-400.0-0.04i)
'-0.0-0.0i'.to_c   #=> (-0.0-0.0i)
'1/2+3/4i'.to_c    #=> ((1/2)+(3/4)*i)
'ruby'.to_c        #=> (0+0i)

Полярная форма:

include Math
"1.0@0".to_c        #=> (1+0.0i)
"1.0@#{PI/2}".to_c  #=> (0.0+1i)
"1.0@#{PI}".to_c    #=> (-1+0.0i)

См. Kernel.Complex.

to_d → bigdecimal Показать исходный код
# File ext/bigdecimal/lib/bigdecimal/util.rb, line 72
def to_d
  BigDecimal.interpret_loosely(self)
end

Возвращает результат интерпретации начальных символов в str как BigDecimal.

require 'bigdecimal'
require 'bigdecimal/util'

"0.5".to_d             # => 0.5e0
"123.45e1".to_d        # => 0.12345e4
"45.67 degrees".to_d   # => 0.4567e2

См. также BigDecimal::new.

to_f → число с плавающей точкой Показать исходный код
static VALUE
rb_str_to_f(VALUE str)
{
    return DBL2NUM(rb_str_to_dbl(str, FALSE));
}

Возвращает результат интерпретации начальных символов в self как число с плавающей точкой:

'3.14159'.to_f  # => 3.14159
'1.234e-2'.to_f # => 0.01234

Символы после начального действительного числа (в данном base) игнорируются:

'3.14 (pi to two places)'.to_f # => 3.14

Возвращает ноль, если нет начального действительного числа:

'abcdef'.to_f # => 0.0
to_i(base = 10) → целое Показать исходный код
static VALUE
rb_str_to_i(int argc, VALUE *argv, VALUE str)
{
    int base = 10;

    if (rb_check_arity(argc, 0, 1) && (base = NUM2INT(argv[0])) < 0) {
        rb_raise(rb_eArgError, "invalid radix %d", base);
    }
    return rb_str_to_inum(str, base, FALSE);
}

Возвращает результат интерпретации начальных символов в self как целое число в заданном base (которое должно быть в (0, 2..36)):

'123456'.to_i     # => 123456
'123def'.to_i(16) # => 1195503

При base равном нулю, строка object может содержать начальные символы для указания фактического основания:

'123def'.to_i(0)   # => 123
'0123def'.to_i(0)  # => 83
'0b123def'.to_i(0) # => 1
'0o123def'.to_i(0) # => 83
'0d123def'.to_i(0) # => 123
'0x123def'.to_i(0) # => 1195503

Символы после начального действительного числа (в данном base) игнорируются:

'12.345'.to_i   # => 12
'12345'.to_i(2) # => 1

Возвращает ноль, если нет начального действительного числа:

'abcdef'.to_i # => 0
'2'.to_i(2)   # => 0
to_r → рациональное Показать исходный код
static VALUE
string_to_r(VALUE self)
{
    VALUE num;

    rb_must_asciicompat(self);

    num = parse_rat(RSTRING_PTR(self), RSTRING_END(self), 0, TRUE);

    if (RB_FLOAT_TYPE_P(num) && !FLOAT_ZERO_P(num))
        rb_raise(rb_eFloatDomainError, "Infinity");
    return num;
}

Возвращает результат интерпретации начальных символов в str как рациональное число. Начальные пробелы и лишние символы после конца допустимого числа игнорируются. Последовательности цифр могут быть разделены подчёркиванием. Если в начале str нет допустимого числа, возвращается ноль. Этот метод никогда не генерирует исключение.

'  2  '.to_r       #=> (2/1)
'300/2'.to_r       #=> (150/1)
'-9.2'.to_r        #=> (-46/5)
'-9.2e2'.to_r      #=> (-920/1)
'1_234_567'.to_r   #=> (1234567/1)
'21 June 09'.to_r  #=> (21/1)
'21/06/09'.to_r    #=> (7/2)
'BWV 1079'.to_r    #=> (0/1)

ПРИМЕЧАНИЕ: “0.3”.to_r не то же самое, что 0.3.to_r. Первый эквивалентен “3/10”.to_r, но второй — нет.

"0.3".to_r == 3/10r  #=> true
0.3.to_r   == 3/10r  #=> false

См. также Kernel#Rational.

to_s → self или строка Показать исходный код
static VALUE
rb_str_to_s(VALUE str)
{
    if (rb_obj_class(str) != rb_cString) {
        return str_duplicate(rb_cString, str);
    }
    return str;
}

Возвращает self если self является строкой, или self, преобразованное в строку, если self является подклассом строки.

String#to_str является псевдонимом для String#to_s.

Также псевдоним: to_str
to_str()

Возвращает self если self является строкой, или self преобразованное в строку, если self является подклассом строки.

String#to_str является псевдонимом для String#to_s.

Псевдоним для: to_s
to_sym → символ

Возвращает Symbol, соответствующий str, создавая символ, если он ранее не существовал. См. Symbol#id2name.

"Koala".intern         #=> :Koala
s = 'cat'.to_sym       #=> :cat
s == :cat              #=> true
s = '@cat'.to_sym      #=> :@cat
s == :@cat             #=> true

Это также может использоваться для создания символов, которые нельзя представить с помощью :xxx обозначения.

'cat and dog'.to_sym   #=> :"cat and dog"
Псевдоним для: intern
String#toeuc → строка Показать исходный код
# File ext/nkf/lib/kconv.rb, line 224
def toeuc; Kconv.toeuc(self) end

Преобразовать self в EUC-JP

String#tojis → строка Показать исходный код
# File ext/nkf/lib/kconv.rb, line 218
def tojis; Kconv.tojis(self) end

Преобразовать self в ISO-2022-JP

String#tolocale → строка Показать исходный код
# File ext/nkf/lib/kconv.rb, line 254
def tolocale; Kconv.tolocale(self) end

Преобразовать self в кодировку локали

String#tosjis → строка Показать исходный код
# File ext/nkf/lib/kconv.rb, line 230
def tosjis; Kconv.tosjis(self) end

Преобразовать self в Shift_JIS

String#toutf16 → строка Показать исходный код
# File ext/nkf/lib/kconv.rb, line 242
def toutf16; Kconv.toutf16(self) end

Преобразовать self в UTF-16

String#toutf32 → строка Показать исходный код
# File ext/nkf/lib/kconv.rb, line 248
def toutf32; Kconv.toutf32(self) end

Преобразовать self в UTF-32

String#toutf8 → строка Показать исходный код
# File ext/nkf/lib/kconv.rb, line 236
def toutf8; Kconv.toutf8(self) end

Преобразовать self в UTF-8

tr(selector, replacements) → new_string Show source
static VALUE
rb_str_tr(VALUE str, VALUE src, VALUE repl)
{
    str = str_duplicate(rb_cString, str);
    tr_trans(str, src, repl, 0);
    return str;
}

Возвращает копию self с каждым символом, указанным в строке selector, преобразованным в соответствующий символ в строке replacements. Соответствие является позиционным:

  • Каждое вхождение первого символа, указанного в selector, преобразуется в первый символ в replacements.

  • Каждое вхождение второго символа, указанного в selector, преобразуется во второй символ в replacements.

  • И так далее.

Пример:

'hello'.tr('el', 'ip') #=> "hippo"

Если replacements короче, чем selector, он неявно дополняется его собственным последним символом:

'hello'.tr('aeiou', '-')   # => "h-ll-"
'hello'.tr('aeiou', 'AA-') # => "hAll-"

Аргументы selector и replacements должны быть допустимыми селекторами символов (см. Character Selectors), и могут использовать любую из его допустимых форм, включая отрицание, диапазоны и экранирование:

# Negation.
'hello'.tr('^aeiou', '-') # => "-e--o"
# Ranges.
'ibm'.tr('b-z', 'a-z') # => "hal"
# Escapes.
'hel^lo'.tr('\^aeiou', '-')     # => "h-l-l-"    # Escaped leading caret.
'i-b-m'.tr('b\-z', 'a-z')       # => "ibabm"     # Escaped embedded hyphen.
'foo\\bar'.tr('ab\\', 'XYZ')    # => "fooZYXr"   # Escaped backslash.
tr!(selector, replacements) → self or nil Show source
static VALUE
rb_str_tr_bang(VALUE str, VALUE src, VALUE repl)
{
    return tr_trans(str, src, repl, 0);
}

Как String#tr, но изменяет self на месте. Возвращает self, если были внесены какие-либо изменения, nil в противном случае.

tr_s(selector, replacements) → string Show source
static VALUE
rb_str_tr_s(VALUE str, VALUE src, VALUE repl)
{
    str = str_duplicate(rb_cString, str);
    tr_trans(str, src, repl, 1);
    return str;
}

Как String#tr, но также сжимает измененные части переведенной строки; возвращает новую строку (переведенную и сжатую).

'hello'.tr_s('l', 'r')   #=> "hero"
'hello'.tr_s('el', '-')  #=> "h-o"
'hello'.tr_s('el', 'hx') #=> "hhxo"

Связанный: String#squeeze.

tr_s!(selector, replacements) → self or nil Show source
static VALUE
rb_str_tr_s_bang(VALUE str, VALUE src, VALUE repl)
{
    return tr_trans(str, src, repl, 1);
}

Как String#tr_s, но изменяет self на месте. Возвращает self, если были внесены какие-либо изменения, nil в противном случае.

Связанный: String#squeeze!.

undump → string Show source
static VALUE
str_undump(VALUE str)
{
    const char *s = RSTRING_PTR(str);
    const char *s_end = RSTRING_END(str);
    rb_encoding *enc = rb_enc_get(str);
    VALUE undumped = rb_enc_str_new(s, 0L, enc);
    bool utf8 = false;
    bool binary = false;
    int w;

    rb_must_asciicompat(str);
    if (rb_str_is_ascii_only_p(str) == Qfalse) {
        rb_raise(rb_eRuntimeError, "non-ASCII character detected");
    }
    if (!str_null_check(str, &w)) {
        rb_raise(rb_eRuntimeError, "string contains null byte");
    }
    if (RSTRING_LEN(str) < 2) goto invalid_format;
    if (*s != '"') goto invalid_format;

    /* strip '"' at the start */
    s++;

    for (;;) {
        if (s >= s_end) {
            rb_raise(rb_eRuntimeError, "unterminated dumped string");
        }

        if (*s == '"') {
            /* epilogue */
            s++;
            if (s == s_end) {
                /* ascii compatible dumped string */
                break;
            }
            else {
                static const char force_encoding_suffix[] = ".force_encoding(\""; /* "\")" */
                static const char dup_suffix[] = ".dup";
                const char *encname;
                int encidx;
                ptrdiff_t size;

                /* check separately for strings dumped by older versions */
                size = sizeof(dup_suffix) - 1;
                if (s_end - s > size && memcmp(s, dup_suffix, size) == 0) s += size;

                size = sizeof(force_encoding_suffix) - 1;
                if (s_end - s <= size) goto invalid_format;
                if (memcmp(s, force_encoding_suffix, size) != 0) goto invalid_format;
                s += size;

                if (utf8) {
                    rb_raise(rb_eRuntimeError, "dumped string contained Unicode escape but used force_encoding");
                }

                encname = s;
                s = memchr(s, '"', s_end-s);
                size = s - encname;
                if (!s) goto invalid_format;
                if (s_end - s != 2) goto invalid_format;
                if (s[0] != '"' || s[1] != ')') goto invalid_format;

                encidx = rb_enc_find_index2(encname, (long)size);
                if (encidx < 0) {
                    rb_raise(rb_eRuntimeError, "dumped string has unknown encoding name");
                }
                rb_enc_associate_index(undumped, encidx);
            }
            break;
        }

        if (*s == '\\') {
            s++;
            if (s >= s_end) {
                rb_raise(rb_eRuntimeError, "invalid escape");
            }
            undump_after_backslash(undumped, &s, s_end, &enc, &utf8, &binary);
        }
        else {
            rb_str_cat(undumped, s++, 1);
        }
    }

    return undumped;
invalid_format:
    rb_raise(rb_eRuntimeError, "invalid dumped string; not wrapped with '\"' nor '\"...\".force_encoding(\"...\")' form");
}

Возвращает не экранированную версию self:

s_orig = "\f\x00\xff\\\""    # => "\f\u0000\xFF\\\""
s_dumped = s_orig.dump       # => "\"\\f\\x00\\xFF\\\\\\\"\""
s_undumped = s_dumped.undump # => "\f\u0000\xFF\\\""
s_undumped == s_orig         # => true

Связанный: String#dump (обратный к String#undump).

unicode_normalize(form = :nfc) → string Show source
static VALUE
rb_str_unicode_normalize(int argc, VALUE *argv, VALUE str)
{
    return unicode_normalize_common(argc, argv, str, id_normalize);
}

Возвращает копию self с примененной Unicode нормализацией.

Аргумент form должен быть одним из следующих символов (см. Unicode normalization forms):

  • :nfc: Каноническое разложение, за которым следует каноническое составление.

  • :nfd: Каноническое разложение.

  • :nfkc: Совместимое разложение, за которым следует каноническое составление.

  • :nfkd: Совместимое разложение.

Кодировка self должна быть одной из:

  • Encoding::UTF_8

  • Encoding::UTF_16BE

  • Encoding::UTF_16LE

  • Encoding::UTF_32BE

  • Encoding::UTF_32LE

  • Encoding::GB18030

  • Encoding::UCS_2BE

  • Encoding::UCS_4BE

Примеры:

"a\u0300".unicode_normalize      # => "a"
"\u00E0".unicode_normalize(:nfd) # => "a "

Связанный: String#unicode_normalize!, String#unicode_normalized?.

unicode_normalize!(form = :nfc) → self Show source
static VALUE
rb_str_unicode_normalize_bang(int argc, VALUE *argv, VALUE str)
{
    return rb_str_replace(str, unicode_normalize_common(argc, argv, str, id_normalize));
}

Как String#unicode_normalize, за исключением того, что нормализация выполняется над self.

Связанный String#unicode_normalized?.

unicode_normalized?(form = :nfc) → true or false Show source
static VALUE
rb_str_unicode_normalized_p(int argc, VALUE *argv, VALUE str)
{
    return unicode_normalize_common(argc, argv, str, id_normalized_p);
}

Возвращает true, если self находится в заданной form Unicode нормализации, false в противном случае. form должно быть одним из :nfc, :nfd, :nfkc или :nfkd.

Примеры:

"a\u0300".unicode_normalized?       # => false
"a\u0300".unicode_normalized?(:nfd) # => true
"\u00E0".unicode_normalized?        # => true
"\u00E0".unicode_normalized?(:nfd)  # => false

Вызывает исключение, если self не находится в кодировке Unicode:

s = "\xE0".force_encoding('ISO-8859-1')
s.unicode_normalized? # Raises Encoding::CompatibilityError.

Связанный: String#unicode_normalize, String#unicode_normalize!.

unpack(template, offset: 0) → array Show source
# File pack.rb, line 19
def unpack(fmt, offset: 0)
  Primitive.pack_unpack(fmt, offset)
end

Извлекает данные из self, формируя объекты, которые становятся элементами нового массива; возвращает этот массив. См. Packed Data.

unpack1(template, offset: 0) → object Show source
# File pack.rb, line 28
def unpack1(fmt, offset: 0)
  Primitive.pack_unpack1(fmt, offset)
end

Как String#unpack, но распаковывает и возвращает только первый извлеченный объект. См. Packed Data.

upcase(*options) → string Show source
static VALUE
rb_str_upcase(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    OnigCaseFoldType flags = ONIGENC_CASE_UPCASE;
    VALUE ret;

    flags = check_case_options(argc, argv, flags);
    enc = str_true_enc(str);
    if (case_option_single_p(flags, enc, str)) {
        ret = rb_str_new(RSTRING_PTR(str), RSTRING_LEN(str));
        str_enc_copy(ret, str);
        upcase_single(ret);
    }
    else if (flags&ONIGENC_CASE_ASCII_ONLY) {
        ret = rb_str_new(0, RSTRING_LEN(str));
        rb_str_ascii_casemap(str, ret, &flags, enc);
    }
    else {
        ret = rb_str_casemap(str, &flags, enc);
    }

    return ret;
}

Возвращает строку, содержащую символы в верхнем регистре в self:

s = 'Hello World!' # => "Hello World!"
s.upcase           # => "HELLO WORLD!"

Регистр может быть изменен заданными options; см. Case Mapping.

Связанный: String#upcase!, String#downcase, String#downcase!.

upcase!(*options) → self or nil Show source
static VALUE
rb_str_upcase_bang(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    OnigCaseFoldType flags = ONIGENC_CASE_UPCASE;

    flags = check_case_options(argc, argv, flags);
    str_modify_keep_cr(str);
    enc = str_true_enc(str);
    if (case_option_single_p(flags, enc, str)) {
        if (upcase_single(str))
            flags |= ONIGENC_CASE_MODIFIED;
    }
    else if (flags&ONIGENC_CASE_ASCII_ONLY)
        rb_str_ascii_casemap(str, str, &flags, enc);
    else
        str_shared_replace(str, rb_str_casemap(str, &flags, enc));

    if (ONIGENC_CASE_MODIFIED&flags) return str;
    return Qnil;
}

Переводит символы в self в верхний регистр; возвращает self, если были внесены какие-либо изменения, nil в противном случае:

s = 'Hello World!' # => "Hello World!"
s.upcase!          # => "HELLO WORLD!"
s                  # => "HELLO WORLD!"
s.upcase!          # => nil

Регистр может быть изменен заданными options; см. Case Mapping.

Связанный: String#upcase, String#downcase, String#downcase!.

upto(other_string, exclusive = false) {|string| ... } → self Show source
upto(other_string, exclusive = false) → new_enumerator
static VALUE
rb_str_upto(int argc, VALUE *argv, VALUE beg)
{
    VALUE end, exclusive;

    rb_scan_args(argc, argv, "11", &end, &exclusive);
    RETURN_ENUMERATOR(beg, argc, argv);
    return rb_str_upto_each(beg, end, RTEST(exclusive), str_upto_i, Qnil);
}

Если блок задан, вызывает блок с каждым значением String, возвращаемым последовательными вызовами String#succ; первое значение - self, следующее - self.succ, и так далее; последовательность завершается, когда достигается значение other_string; возвращает self:

'a8'.upto('b6') {|s| print s, ' ' } # => "a8"

Вывод:

a8 a9 b0 b1 b2 b3 b4 b5 b6

Если аргумент exclusive задан как истинное значение, последнее значение опускается:

'a8'.upto('b6', true) {|s| print s, ' ' } # => "a8"

Вывод:

a8 a9 b0 b1 b2 b3 b4 b5

Если other_string не будет достигнуто, блок не вызывается:

'25'.upto('5') {|s| fail s }
'aa'.upto('a') {|s| fail s }

Без блока возвращает новый перечислитель:

'a8'.upto('b6') # => #<Enumerator: "a8":upto("b6")>
valid_encoding? → true или false Показать исходный код
static VALUE
rb_str_valid_encoding_p(VALUE str)
{
    int cr = rb_enc_str_coderange(str);

    return RBOOL(cr != ENC_CODERANGE_BROKEN);
}

Возвращает значение true, если self закодировано корректно, false, в противном случае:

"\xc2\xa1".force_encoding("UTF-8").valid_encoding? # => true
"\xc2".force_encoding("UTF-8").valid_encoding?     # => false
"\x80".force_encoding("UTF-8").valid_encoding?     # => false

Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API