Spec-Zone.ru › Ruby 3.3

класс String

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

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

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

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

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

  • литерала heredoc.

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

  • Метода String.

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

В общем случае, если существуют как версия метода с восклицательным знаком, так и без него, версия с восклицательным знаком изменяет исходный объект, а версия без него — нет. Однако метод без восклицательного знака также может изменять объект, например, 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 для получения подробной информации.

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

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

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

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

  • \+ соответствует $+, которая содержит последнюю группу захвата.

См. Regexp для получения подробной информации.

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

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

Обратная ссылка обычно предваряется дополнительным обратным слэшем. Например, если вы хотите записать обратную ссылку \& в 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]

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

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

Что здесь

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

  • Наследуется от класса Объект.

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

Здесь класс 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 если строка находится в нормализованной форме Unicode; 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 если строка равна заданной строке после свертывания Unicode регистра; 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!: Нормализует Unicode 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);
                assert(RSTRING_LEN(str) + 1 <= str_embed_capa(str));
                memcpy(new_ptr, RSTRING(str)->as.embed.ary, RSTRING_LEN(str) + 1);
                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_LEN(str) + 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));
            }
            STR_SET_LEN(str, 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, у строковой литерали типа '' или литерала here document всегда используется кодировка сценария.)

С необязательным ключевым аргументом 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 должно быть Array или Hash, содержащим значения для подстановки:

"%-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 удобнее для определения констант:

FILENAME = -'config/database.yml'

в то время как dedup лучше подходит для использования метода в цепочках вычислений:

@url_list.concat(urls.map(&:dedup))
Также алиасируется как: 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);
    }
}

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

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

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

Если данное значение не является регулярным выражением, возвращает значение, возвращаемое 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_update(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"
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 (STR_EMBED_P(str)) {
        str2 = str_alloc_embed(rb_cString, RSTRING_LEN(str) + TERM_LEN(str));
    }
    else {
        str2 = str_alloc_heap(rb_cString);
    }
    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) → integer or nil Показать исходный код
byteindex(regexp, offset = 0) → integer or 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) {
        long slen = RSTRING_LEN(str);
        pos = NUM2LONG(initpos);
        if (pos < 0 ? (pos += slen) < 0 : pos > slen) {
            if (RB_TYPE_P(sub, T_REGEXP)) {
                rb_backref_set(Qnil);
            }
            return Qnil;
        }
    }
    else {
        pos = 0;
    }

    str_ensure_byte_pos(str, pos);

    if (RB_TYPE_P(sub, T_REGEXP)) {
        if (rb_reg_search(sub, str, pos, 0) >= 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_byteindex(str, sub, pos);
        if (pos >= 0) return LONG2NUM(pos);
    }
    return Qnil;
}

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

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

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

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

Аргумент Integer 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) → integer or nil Показать исходный код
byterindex(regexp, offset = self.bytesize) → integer or nil
static VALUE
rb_str_byterindex_m(int argc, VALUE *argv, VALUE str)
{
    VALUE sub;
    VALUE initpos;
    long pos, len = RSTRING_LEN(str);

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

    str_ensure_byte_pos(str, 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;
}

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

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

Возвращает Integer байтовый индекс последнего совпадения для заданного Regexp regexp, или 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">

Аргумент Integer 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 является отрицательным Integer, максимальная стартовая позиция в строке, до которой проводится поиск, равна сумме длины строки и 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 → array_of_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 → integer Показать исходный код
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) → string or nil
byteslice(range) → string or 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) → string
bytesplice(index, length, str, str_index, str_length) → string
bytesplice(range, str) → string
bytesplice(range, str, str_range) → string
static VALUE
rb_str_bytesplice(int argc, VALUE *argv, VALUE str)
{
    long beg, len, vbeg, vlen;
    VALUE val;
    rb_encoding *enc;
    int cr;

    rb_check_arity(argc, 2, 5);
    if (!(argc == 2 || argc == 3 || argc == 5)) {
        rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 2, 3, or 5)", argc);
    }
    if (argc == 2 || (argc == 3 && !RB_INTEGER_TYPE_P(argv[0]))) {
        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];
        StringValue(val);
        if (argc == 2) {
            /* bytesplice(range, str) */
            vbeg = 0;
            vlen = RSTRING_LEN(val);
        }
        else {
            /* bytesplice(range, str, str_range) */
            if (!rb_range_beg_len(argv[2], &vbeg, &vlen, RSTRING_LEN(val), 2)) {
                rb_raise(rb_eTypeError, "wrong argument type %s (expected Range)",
                         rb_builtin_class_name(argv[2]));
            }
        }
    }
    else {
        beg = NUM2LONG(argv[0]);
        len = NUM2LONG(argv[1]);
        val = argv[2];
        StringValue(val);
        if (argc == 3) {
            /* bytesplice(index, length, str) */
            vbeg = 0;
            vlen = RSTRING_LEN(val);
        }
        else {
            /* bytesplice(index, length, str, str_index, str_length) */
            vbeg = NUM2LONG(argv[3]);
            vlen = NUM2LONG(argv[4]);
        }
    }
    str_check_beg_len(str, &beg, &len);
    str_check_beg_len(val, &vbeg, &vlen);
    enc = rb_enc_check(str, val);
    str_modify_keep_cr(str);
    rb_str_update_1(str, beg, len, val, vbeg, vlen);
    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 str;
}

Заменяет часть или всё содержимое self на str, и возвращает self. Часть строки, которая подвергается замене, определяется теми же правилами, что и у String#byteslice, за исключением того, что length не может быть опущено. Если строка замены имеет длину, отличающуюся от длины заменяемого текста, строка будет соответствующим образом скорректирована.

Если str_index и str_length, или str_range заданы, содержимое self заменяется на str.byteslice(str_index, str_length) или str.byteslice(str_range); однако подстрока str не выделяется как новая строка.

Форма, которая принимает Integer, вызовет IndexError, если значение находится вне допустимого диапазона; форма с Range вызовет RangeError. Если начальное или конечное смещение не совпадает с границей символа (кодовой точки), будет вызвано IndexError.

capitalize(*options) → string Показать исходный код
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 or 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, or 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, or 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.

END_OF_DOCUMENT_MARKER
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 && argc < 2) 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_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 , который является Integer, значение рассматривается как кодовая точка и преобразуется в символ перед конкатенацией:

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) очень слабо. Согласно его справке, традиционный вывод crypt(3) в Linux имеет только 2**56 вариаций; это слишком легко взломать сегодня. И это поведение по умолчанию.

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

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

      "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$ считается полностью неисправным: см. справку FreeBSD.

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

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

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

-string → frozen_string
dedup → frozen_string

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

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

Обратите внимание, что вариант -string удобнее для определения констант:

FILENAME = -'config/database.yml'

в то время как dedup лучше подходит для использования метода в цепочках вычислений:

@url_list.concat(urls.map(&:dedup))
Псевдоним для: -@
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 Показать исходный код
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 с удалённой лидирующей подстрокой %%%CODE_BLOCK_760%%з:

'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 Показать исходный код
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 Показать исходный код
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 Показать исходный код
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 Показать исходный код
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_direct(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; см. Преобразование регистра.

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

downcase!(*options) → self or nil Показать исходный код
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; см. Преобразование регистра.

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

dump → string Показать исходный код
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).

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;

    for (i=0; i<argc; i++) {
        VALUE tmp = argv[i];
        const char *p, *s, *e;
        long slen, tlen;
        rb_encoding *enc;

        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 (!at_char_boundary(p, s, e, enc))
            continue;
        if (memcmp(s, RSTRING_PTR(tmp), tlen) == 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 Показать исходный код
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_encoding *encoding = rb_to_encoding(enc);
    int idx = rb_enc_to_index(encoding);

    // If the encoding is unchanged, we do nothing.
    if (ENCODING_GET(str) == idx) {
        return str;
    }

    rb_enc_associate_index(str, idx);

    // If the coderange was 7bit and the new encoding is ASCII-compatible
    // we can keep the coderange.
    if (ENC_CODERANGE(str) == ENC_CODERANGE_7BIT && encoding && rb_enc_asciicompat(encoding)) {
        return str;
    }

    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
getbyte(index) → integer or nil Показать исходный код
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) → integer or nil Показать исходный код
index(regexp, offset = 0) → integer or nil
static VALUE
rb_str_index_m(int argc, VALUE *argv, VALUE str)
{
    VALUE sub;
    VALUE initpos;
    rb_encoding *enc = STR_ENC_GET(str);
    long pos;

    if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) {
        long slen = str_strlen(str, enc); /* str's enc */
        pos = NUM2LONG(initpos);
        if (pos < 0 ? (pos += slen) < 0 : pos > slen) {
            if (RB_TYPE_P(sub, T_REGEXP)) {
                rb_backref_set(Qnil);
            }
            return Qnil;
        }
    }
    else {
        pos = 0;
    }

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

        if (rb_reg_search(sub, str, pos, 0) >= 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_index(str, sub, pos);
        if (pos >= 0) {
            pos = rb_str_sublen(str, pos);
            return LONG2NUM(pos);
        }
    }
    return Qnil;
}

Возвращает целое значение индекса первого совпадения для заданного аргумента или 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
Также алиасирован как: заменить
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_update(str, pos, 0, str2);
    return str;
}

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

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

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

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

'foo'.insert(-2, 'bar') # => "fobaro"
inspect → string Показать исходный код
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;

    GLOBAL_SYMBOLS_ENTER(symbols);
    {
        sym = lookup_str_sym_with_lock(symbols, str);

        if (sym) {
            // ok
        }
        else if (USE_SYMBOL_GC) {
            rb_encoding *enc = rb_enc_get(str);
            rb_encoding *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);
            int 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 id = intern_str(str, 0);
            sym = ID2SYM(id);
        }
    }
    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
Также алиасирован как: 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!.

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_direct(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 initpos;
    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, &initpos) == 2) {
        pos = NUM2LONG(initpos);
        if (pos < 0 && (pos += len) < 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_enc_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) {
            pos = rb_str_sublen(str, pos);
            return LONG2NUM(pos);
        }
    }
    return Qnil;
}

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

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

Возвращает Integer индекс последнего совпадения с заданным 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">

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

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

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

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

Integer аргумент 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 является отрицательным Integer, максимальная начальная позиция в строке для завершения поиска — сумма длины строки и 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 Показать исходный код
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] Показать исходный код
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;
        }
    }

    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 Показать исходный код
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 Показать исходный код
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 Показать исходный код
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 Показать исходный код
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 Показать исходный код
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 Показать исходный код
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 Показать исходный код
# File lib/shellwords.rb, line 226
def shellescape
  Shellwords.escape(self)
end

Экранирует str таким образом, чтобы его можно было безопасно использовать в командной строке оболочки Bourne.

См. Shellwords.shellescape для подробностей.

shellsplit → array Показать исходный код
# File lib/shellwords.rb, line 215
def shellsplit
  Shellwords.split(self)
end

Разбивает str на массив токенов таким же образом, как это делает оболочка Bourne UNIX.

См. Shellwords.shellsplit для подробностей.

size
Псевдоним для: length
slice
Псевдоним для: []
slice!(index) → new_string or nil Показать исходный код
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 Slices.

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

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))

    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;

        if (result) result = rb_ary_new();
        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);

        if (result) result = rb_ary_new();
        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;

        if (result) result = rb_ary_new_capa(RSTRING_LEN(str));
        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 {
        if (result) result = rb_ary_new();
        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, разбиение происходит по каждому вхождению field_sep; пустые подстроки в конце не возвращаются:

'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, «сжатыми» (см. Multiple Character 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 {
            const char *p, *s, *e;
            long slen, tlen;
            rb_encoding *enc;

            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 = p + tlen;
            if (!at_char_right_boundary(p, s, e, enc))
                continue;
            if (memcmp(p, RSTRING_PTR(tmp), tlen) == 0)
                return Qtrue;
        }
    }
    return Qfalse;
}

Возвращает значение true, если 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 in Strings:

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; возвращает 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.

См. Substitution Methods.

Связанно с: 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);

        RB_GC_GUARD(match);

        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 # => ""
Также алиасы: next
succ! → self Показать исходный код
static VALUE
rb_str_succ_bang(VALUE str)
{
    rb_str_modify(str);
    str_succ(str);
    return str;
}

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

Также алиасы: next!
sum(n = 16) → integer Показать исходный код
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) → string Показать исходный код
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 or 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 → complex Показать исходный код
static VALUE
string_to_c(VALUE self)
{
    VALUE num;

    rb_must_asciicompat(self);

    (void)parse_comp(rb_str_fill_terminator(self, 1), FALSE, &num);

    return num;
}

Возвращает self , интерпретируемое как объект Complex; начальные пробелы и конечный мусор игнорируются:

'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)
'1.0@0'.to_c             # => (1+0.0i)
"1.0@#{Math::PI/2}".to_c # => (0.0+1i)
"1.0@#{Math::PI}".to_c   # => (-1+0.0i)

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

'ruby'.to_c        # => (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

См. также Kernel.BigDecimal.

to_f → float Показать исходный код
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) → integer Показать исходный код
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 → rational Показать исходный код
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 or string Показать исходный код
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 является подклассом строки.

Также алиасы: to_str
to_str
Псевдоним для: to_s
to_sym → symbol

Возвращает 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 → string Показать исходный код
# File ext/nkf/lib/kconv.rb, line 224
def toeuc; Kconv.toeuc(self) end

Преобразовать self в EUC-JP

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

Преобразовать self в ISO-2022-JP

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

Преобразовать self в кодировку локали

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

Преобразовать self в Shift_JIS

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

Преобразовать self в UTF-16

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

Преобразовать self в UTF-32

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

Преобразовать self в UTF-8

tr(selector, replacements) → new_string Показать исходный код
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 должны быть допустимыми селекторами символов (см. Селекторы символов), и могут использовать любую их допустимую форму, включая отрицание, диапазоны и экранирование:

# 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 Показать исходный код
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 Показать исходный код
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 Показать исходный код
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 Показать исходный код
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);
        }
    }

    RB_GC_GUARD(str);

    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).

END_OF_DOCUMENT_MARKER
upto(other_string, exclusive = false) {|string| ... } → self Показать исходный код
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#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 or 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