Spec-Zone.ru › Ruby 3

класс String

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

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

Из-за проблем с алиасингом пользователи строк должны быть осведомлены о методах, которые изменяют содержимое объекта String. Как правило, методы с именами, оканчивающимися на «!», изменяют свой получатель, а те, у которых нет «!», возвращают новый String. Однако существуют исключения, например, String#[]=.

Публичные методы класса

new(string = '') → new_string Показать исходный код
new(string = '', encoding: encoding) → new_string
new(string = '', capacity: size) → 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 (venc != Qundef && !NIL_P(venc)) {
            enc = rb_to_encoding(venc);
        }
        if (vcapa != Qundef && !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);
                memcpy(new_ptr, RSTRING(str)->as.ary, RSTRING_EMBED_LEN_MAX + 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(str)->as.heap.len + TERM_LEN(str);
                char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
                memcpy(new_ptr, old_ptr, osize < size ? osize : size);
                FL_UNSET_RAW(str, STR_SHARED);
                RSTRING(str)->as.heap.ptr = new_ptr;
            }
            else if (STR_HEAP_SIZE(str) != (size_t)capa + termlen) {
                SIZED_REALLOC_N(RSTRING(str)->as.heap.ptr, char,
                        (size_t)capa + termlen, STR_HEAP_SIZE(str));
            }
            RSTRING(str)->as.heap.len = len;
            TERM_FILL(&RSTRING(str)->as.heap.ptr[len], termlen);
            if (n == 1) {
                memcpy(RSTRING(str)->as.heap.ptr, RSTRING_PTR(orig), len);
                rb_enc_cr_str_exact_copy(str, orig);
            }
            FL_SET(str, STR_NOEMBED);
            RSTRING(str)->as.heap.aux.capa = capa;
        }
        else if (n == 1) {
            rb_str_replace(str, orig);
        }
        if (enc) {
            rb_enc_associate(str, enc);
            ENC_CODERANGE_CLEAR(str);
        }
    }
    else if (n == 1) {
        rb_str_replace(str, orig);
    }
    return str;
}

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

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

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

С одним аргументом String string, возвращает копию string с той же кодировкой, что и string:

s = String.new("Que veut dire \u{e7}a?")
s # => "Que veut dire \u{e7}a?"
s.encoding # => #<Encoding:UTF-8>

Литеральные строки, такие как "" или здесь-документы, всегда используют кодировку сценария, в отличие от String.new.

С ключевым аргументом encoding, возвращает копию str с указанной кодировкой:

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

Обратите внимание, что эти варианты эквивалентны:

s0 = String.new('foo', encoding: 'ASCII')
s1 = 'foo'.force_encoding('ASCII')
s0.encoding == s1.encoding # => true

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

String.new(capacity: 1) # => ""
String.new(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.

Методы публичного экземпляра

string % object → new_string Показать исходный код
static VALUE
rb_str_format_m(VALUE str, VALUE arg)
{
    VALUE tmp = rb_check_array_type(arg);

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

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

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

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

"%-5s: %016x" % [ "ID", self.object_id ] # => "ID   : 00002b054ec93168"
"foo = %{foo}" % {foo: 'bar'} # => "foo = bar"
"foo = %{foo}, baz = %{baz}" % {foo: 'bar', baz: 'bat'} # => "foo = bar, baz = bat"
string * integer → new_string Показать исходный код
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(rb_cString);
        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) {
       str2 = str_alloc(rb_cString);
       if (!STR_EMBEDDABLE_P(len, 1)) {
           RSTRING(str2)->as.heap.aux.capa = len;
           RSTRING(str2)->as.heap.ptr = ZALLOC_N(char, (size_t)len + 1);
           STR_SET_NOEMBED(str2);
       }
       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 # => ""
string + other_string → new_string Показать исходный код
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"
+string → new_string or self Показать исходный код
static VALUE
str_uplus(VALUE str)
{
    if (OBJ_FROZEN(str)) {
        return rb_str_dup(str);
    }
    else {
        return str;
    }
}

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

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

-string → frozen_string Показать исходный код
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 << object → str Показать исходный код
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_enc_to_index(enc);
    if (encidx == ENCINDEX_ASCII || encidx == ENCINDEX_US_ASCII) {
        /* US-ASCII automatically extended to ASCII-8BIT */
        char buf[1];
        buf[0] = (char)code;
        if (code > 0xFF) {
            rb_raise(rb_eRangeError, "%u out of char range", code);
        }
        rb_str_cat(str1, buf, 1);
        if (encidx == ENCINDEX_US_ASCII && code > 127) {
            rb_enc_associate_index(str1, ENCINDEX_ASCII);
            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;
}

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

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

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

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

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

string <=> other_string → -1, 0, 1, or 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
string == object → true or 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.==.

Также псевдоним: ===
string === object → true or 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.==.

Псевдоним для: ==
string =~ regexp → integer or nil Показать исходный код
string =~ object → integer or nil
static VALUE
rb_str_match(VALUE x, VALUE y)
{
    switch (OBJ_BUILTIN_TYPE(y)) {
      case T_STRING:
        rb_raise(rb_eTypeError, "type mismatch: String given");

      case T_REGEXP:
        return rb_reg_match(y, x);

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

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

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

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

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

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

number= nil
"no. 9" =~ /(?<number>\d+)/
number # => nil (not assigned)
/(?<number>\d+)/ =~ "no. 9"
number #=> "9"
string[index] → new_string or nil Показать исходный код
string[start, length] → new_string or nil
string[range] → new_string or nil
string[regexp, capture = 0] → new_string or nil
string[substring] → new_string or 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, заданную аргументами.

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

'bar'[2] # => "r"

Считает назад от конца self если index отрицательно:

'foo'[-3] # => "f"

Возвращает nil если index выходит за пределы диапазона:

'foo'[3] # => nil
'foo'[-4] # => nil

Когда заданы два целочисленных аргумента start и length, возвращает подстроку заданной length, найденную в self по смещению start:

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

Считает назад от конца self если start отрицательно:

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

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

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

Возвращает nil если start выходит за пределы диапазона:

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

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

'foo'[1, 50] # => "oo"

Возвращает nil если length отрицательно:

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

Когда задан единственный диапазон range, вычисляет значения start и length из данного range, и возвращает значения, как описано выше:

  • 'foo'[0..1] эквивалентно 'foo'[0, 2].

  • 'foo'[0...1] эквивалентно 'foo'[0, 1].

Когда задан аргумент Regexp regexp, и аргумент capture равен 0, возвращает первую найденную совпадающую подстроку в self, или nil если ничего не найдено:

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

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

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"

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

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

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

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

Также псевдоним: slice
str[integer] = new_str Показать исходный код
str[integer, integer] = new_str
str[range] = aString
str[regexp] = new_str
str[regexp, integer] = new_str
str[regexp, name] = new_str
str[other_str] = new_str
static VALUE
rb_str_aset_m(int argc, VALUE *argv, VALUE str)
{
    if (argc == 3) {
        if (RB_TYPE_P(argv[0], T_REGEXP)) {
            rb_str_subpat_set(str, argv[0], argv[1], argv[2]);
        }
        else {
            rb_str_splice(str, NUM2LONG(argv[0]), NUM2LONG(argv[1]), argv[2]);
        }
        return argv[2];
    }
    rb_check_arity(argc, 2, 3);
    return rb_str_aset(str, argv[0], argv[1]);
}

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

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

    return cr == ENC_CODERANGE_7BIT ? Qtrue : Qfalse;
}

Возвращает true для строки, содержащей только символы ASCII.

"abc".force_encoding("UTF-8").ascii_only?          #=> true
"abc\u{6666}".force_encoding("UTF-8").ascii_only?  #=> false
b → str Показать исходный код
static VALUE
rb_str_b(VALUE str)
{
    VALUE str2 = str_alloc(rb_cString);
    str_replace_shared_without_enc(str2, str);
    ENC_CODERANGE_CLEAR(str2);
    return str2;
}

Возвращает скопированную строку с кодировкой ASCII-8BIT.

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

Возвращает массив байтов в str. Это сокращенная форма записи str.each_byte.to_a.

Если задан блок, что является устаревшей формой, он работает так же, как each_byte.

bytesize → целое число Показать исходный код
static VALUE
rb_str_bytesize(VALUE str)
{
    return LONG2NUM(RSTRING_LEN(str));
}

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

"\x80\u3042".bytesize # => 4
"hello".bytesize # => 5

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

byteslice(целое число) → новая_строка или nil Показать исходный код
byteslice(целое число, целое число) → новая_строка или nil
byteslice(диапазон) → новая_строка или nil
static VALUE
rb_str_byteslice(int argc, VALUE *argv, VALUE str)
{
    if (argc == 2) {
        long beg = NUM2LONG(argv[0]);
        long end = NUM2LONG(argv[1]);
        return str_byte_substr(str, beg, end, TRUE);
    }
    rb_check_arity(argc, 1, 2);
    return str_byte_aref(str, argv[0]);
}

Ссылочная работа с байтами — Если передано одно Integer, возвращается подстрока длиной в один байт в указанной позиции. Если переданы два Integer, возвращается подстрока, начинающаяся с смещения, заданного первым, и имеющая длину, заданную вторым. Если задан Range, возвращается подстрока, содержащая байты в позициях, заданных диапазоном. Во всех трёх случаях, если смещение отрицательное, оно отсчитывается от конца str. Возвращает nil если начальное смещение выходит за пределы строки, длина отрицательная или начало диапазона больше конца. Кодировка результирующей строки сохраняет исходную кодировку.

"hello".byteslice(1)     #=> "e"
"hello".byteslice(-1)    #=> "o"
"hello".byteslice(1, 2)  #=> "el"
"\x80\u3042".byteslice(1, 3) #=> "\u3042"
"\x03\u3042\xff".byteslice(1..3) #=> "\u3042"
capitalize → новая_строка Показать исходный код
capitalize([options]) → новая_строка
static VALUE
rb_str_capitalize(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    OnigCaseFoldType flags = ONIGENC_CASE_UPCASE | ONIGENC_CASE_TITLECASE;
    VALUE ret;

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

Возвращает копию str с первым символом в верхнем регистре, а остальные — в нижнем.

См. String#downcase для значения options и использования с различными кодировками.

"hello".capitalize    #=> "Hello"
"HELLO".capitalize    #=> "Hello"
"123ABC".capitalize   #=> "123abc"
capitalize! → str или nil Показать исходный код
capitalize!([options]) → str или 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;
}

Изменяет str, преобразуя первый символ в верхний регистр, а остальные — в нижний. Возвращает nil если изменений не было. Существует исключение для современной грузинской (mkhedruli/MTAVRULI), где результат такой же, как для String#downcase, чтобы избежать смешанного регистра.

См. String#downcase для значения options и использования с различными кодировками.

a = "hello"
a.capitalize!   #=> "Hello"
a               #=> "Hello"
a.capitalize!   #=> nil
casecmp(other_str) → -1, 0, 1 или nil Показать исходный код
static VALUE
rb_str_casecmp(VALUE str1, VALUE str2)
{
    VALUE s = rb_check_string_type(str2);
    if (NIL_P(s)) {
        return Qnil;
    }
    return str_casecmp(str1, s);
}

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

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

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

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

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

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

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

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

'foo'.casecmp?(1) # => nil
center(width, padstr=' ') → новая_строка Показать исходный код
static VALUE
rb_str_center(int argc, VALUE *argv, VALUE str)
{
    return rb_str_justify(argc, argv, str, 'c');
}

Центрирует str в width. Если width больше длины str, возвращает новую String длиной width с str по центру и заполненную padstr; в противном случае возвращает str.

"hello".center(4)         #=> "hello"
"hello".center(20)        #=> "       hello        "
"hello".center(20, '123') #=> "1231231hello12312312"
chars → массив Показать исходный код
static VALUE
rb_str_chars(VALUE str)
{
    VALUE ary = WANTARRAY("chars", rb_str_strlen(str));
    return rb_str_enumerate_chars(str, ary);
}

Возвращает массив символов в str. Это сокращенная форма записи str.each_char.to_a.

Если задан блок, что является устаревшей формой, он работает так же, как each_char.

chomp(separator=$/) → новая_строка Показать исходный код
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));
}

Возвращает новую String с удалённым разделителем строк с конца str (если он есть). Если $/ не был изменён от значения по умолчанию разделителя строк Ruby, то chomp также удаляет символы возврата каретки (то есть удалит \n, \r, и \r\n). Если $/ является пустой строкой, он удалит все заключительные символы новой строки из строки.

"hello".chomp                #=> "hello"
"hello\n".chomp              #=> "hello"
"hello\r\n".chomp            #=> "hello"
"hello\n\r".chomp            #=> "hello\n"
"hello\r".chomp              #=> "hello"
"hello \n there".chomp       #=> "hello \n there"
"hello".chomp("llo")         #=> "he"
"hello\r\n\r\n".chomp('')    #=> "hello"
"hello\r\n\r\r\n".chomp('')  #=> "hello\r\n\r"
chomp!(separator=$/) → str или nil Показать исходный код
static VALUE
rb_str_chomp_bang(int argc, VALUE *argv, VALUE str)
{
    VALUE rs;
    str_modifiable(str);
    if (RSTRING_LEN(str) == 0) return Qnil;
    rs = chomp_rs(argc, argv);
    if (NIL_P(rs)) return Qnil;
    return rb_str_chomp_string(str, rs);
}

Изменяет str в соответствии с описанием для String#chomp, возвращая str или nil если изменений не было.

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

Возвращает новую String со удалённым последним символом. Если строка заканчивается на \r\n, удаляются оба символа. Применение chop к пустой строке возвращает пустую строку. String#chomp часто является более безопасной альтернативой, так как она оставляет строку неизменной, если она не заканчивается разделителем записей.

"string\r\n".chop   #=> "string"
"string\n\r".chop   #=> "string\n"
"string\n".chop     #=> "string"
"string".chop       #=> "strin"
"x".chop.chop       #=> ""
chop! → str 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;
}

Обрабатывает str так же, как для String#chop, возвращая str или nil, если str пустая. Также см. String#chomp!.

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

Возвращает строку из одного символа в начале строки.

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

Очищает строку.

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

Возвращает массив порядковых номеров Integer символов в str. Это сокращение для str.each_codepoint.to_a.

Если задан блок, что является устаревшей формой, работает так же, как each_codepoint.

concat(*objects) → new_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;
}

Возвращает новую строку, содержащую конкатенацию self и всех объектов в objects:

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

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

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

Связанные: String#<<, принимающий один аргумент.

count([other_str]+) → 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;

    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 n = 0;
            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 INT2NUM(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);
    i = 0;
    while (s < send) {
        unsigned int c;

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

    return INT2NUM(i);
}

Каждый other_str параметр определяет набор символов для подсчёта. Пересечение этих наборов определяет символы для подсчёта в str. Любой other_str начинающийся с знака возведения в степень ^ инвертируется. Последовательность c1-c2 означает все символы между c1 и c2. Обратная косая черта \ может использоваться для экранирования ^ или - и в противном случае игнорируется, если она не появляется в конце последовательности или в конце other_str.

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_str Показать исходный код
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() (void)0
#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);
    if (RSTRING_LEN(salt) < 2) {
        goto short_salt;
    }

    s = StringValueCStr(str);
    saltp = RSTRING_PTR(salt);
    if (!saltp[0] || !saltp[1]) goto short_salt;
#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
    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;

  short_salt:
    rb_raise(rb_eArgError, "salt too short (need >=2 bytes)");
    UNREACHABLE_RETURN(Qundef);
}

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

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

  • В некоторых ОС, таких как Mac OS, crypt(3) никогда не терпит неудачу (т.е. молча приводит к неожиданным результатам).

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

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

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

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

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

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

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

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

delete([other_str]+) → new_str Показать исходный код
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;
}

Возвращает копию str со всеми символами, входящими в пересечение своих аргументов, удалёнными. Использует те же правила для построения набора символов, что и String#count.

"hello".delete "l","lo"        #=> "heo"
"hello".delete "lo"            #=> "he"
"hello".delete "aeiou", "^e"   #=> "hell"
"hello".delete "ej-m"          #=> "ho"
delete!([other_str]+) → str 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;
}

Выполняет операцию delete на месте, возвращая str или nil, если str не была изменена.

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

Возвращает копию str с удалёнными начальными prefix.

"hello".delete_prefix("hel") #=> "lo"
"hello".delete_prefix("llo") #=> "hello"
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);
}

Удаляет начальные prefix из str, возвращая nil, если изменений не было.

"hello".delete_prefix!("hel") #=> "lo"
"hello".delete_prefix!("llo") #=> nil
delete_suffix(suffix) → new_str Показать исходный код
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);
}

Возвращает копию str с удалёнными конечными suffix.

"hello".delete_suffix("llo") #=> "he"
"hello".delete_suffix("hel") #=> "hello"
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;
}

Удаляет конечные suffix из str, возвращая nil, если изменений не было.

"hello".delete_suffix!("llo") #=> "he"
"hello".delete_suffix!("hel") #=> nil
downcase → new_str Показать исходный код
downcase([options]) → new_str
static VALUE
rb_str_downcase(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    OnigCaseFoldType flags = ONIGENC_CASE_DOWNCASE;
    VALUE ret;

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

    return ret;
}

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

Значение параметров options таково:

Без опций

Полное отображение Unicode-регистра, подходящее для большинства языков (см. опции :turkic и :lithuanian для исключений). Зависимое от контекста отображение регистра, как описано в таблице 3-14 стандарта Unicode, в настоящее время не поддерживается.

:ascii

Затрагиваются только символы ASCII-диапазона, т. е. символы «A» до «Z» и «a» до «z». Данную опцию нельзя комбинировать с другими опциями.

:turkic

Полное отображение Unicode-регистра, адаптированное для тюркских языков (турецкий, азербайджанский и т. д.). Это означает, что заглавная буква I отображается в строчную букву i без точки, и так далее.

:lithuanian

В настоящее время используется полное отображение Unicode-регистра. В будущем будет реализовано полное отображение Unicode-регистра, адаптированное для литовского языка (поддерживая точку в строчной букве i даже при наличии диакритического знака сверху).

:fold

Доступно только в downcase и downcase!. Сворачивание Unicode-регистра, которое более масштабно, чем отображение Unicode-регистра. В настоящее время данная опция не может быть объединена ни с какой другой опцией (т. е. в настоящее время нет варианта для тюркских языков).

Обратите внимание, что некоторые предположения, справедливые для преобразований регистра только в ASCII, не действуют для более общих преобразований регистра. Например, длина результата может отличаться от длины входных данных (ни в символах, ни в байтах), некоторые предположения о обратном преобразовании (например, str.downcase == str.upcase.downcase) могут не применяться, и нормализация Unicode (т. е. String#unicode_normalize) не обязательно сохраняется операциями преобразования регистра.

Преобразование/сворачивание регистра для символов, не являющихся ASCII, в настоящее время поддерживается для строк/символов UTF-8, UTF-16BE/LE, UTF-32BE/LE и ISO-8859-1~16. Поддержка будет расширена до других кодировок.

"hEllO".downcase   #=> "hello"
downcase! → str or nil Показать исходный код
downcase!([options]) → str 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;
}

Преобразует содержимое str в строчные буквы, возвращая nil , если изменений не было.

См. String#downcase для значения options и использования с различными кодировками.

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

Возвращает цитированную версию строки, в которой все непечатаемые символы заменены обозначением \xHH и все специальные символы экранированы.

Этот метод может быть использован для обратного преобразования: если полученная new_str интерпретируется с помощью eval, она произведёт исходную строку.

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

См. также String#undump.

each_byte {|integer| block } → str Показать исходный код
each_byte → an_enumerator
static VALUE
rb_str_each_byte(VALUE str)
{
    RETURN_SIZED_ENUMERATOR(str, 0, 0, rb_str_each_byte_size);
    return rb_str_enumerate_bytes(str, 0);
}

Передаёт каждый байт в str в заданный блок, или возвращает итератор, если блок не задан.

"hello".each_byte {|c| print c, ' ' }

выводит:

104 101 108 108 111
each_char {|cstr| block } → str Показать исходный код
each_char → an_enumerator
static VALUE
rb_str_each_char(VALUE str)
{
    RETURN_SIZED_ENUMERATOR(str, 0, 0, rb_str_each_char_size);
    return rb_str_enumerate_chars(str, 0);
}

Передаёт каждый символ в str в заданный блок, или возвращает итератор, если блок не задан.

"hello".each_char {|c| print c, ' ' }

выводит:

h e l l o
each_codepoint {|integer| block } → str Показать исходный код
each_codepoint → an_enumerator
static VALUE
rb_str_each_codepoint(VALUE str)
{
    RETURN_SIZED_ENUMERATOR(str, 0, 0, rb_str_each_char_size);
    return rb_str_enumerate_codepoints(str, 0);
}

Передаёт Integer код каждого символа в str, также известный как codepoint при работе со строками Unicode, в заданный блок. Для кодировок, отличных от UTF-8/UTF-16(BE|LE)/UTF-32(BE|LE), значения берутся непосредственно из двоичного представления каждого символа.

Если блок не задан, вместо этого возвращается итератор.

"hello\u0639".each_codepoint {|c| print c, ' ' }

выводит:

104 101 108 108 111 1593
each_grapheme_cluster {|cstr| block } → str Показать исходный код
each_grapheme_cluster → an_enumerator
static VALUE
rb_str_each_grapheme_cluster(VALUE str)
{
    RETURN_SIZED_ENUMERATOR(str, 0, 0, rb_str_each_grapheme_cluster_size);
    return rb_str_enumerate_grapheme_clusters(str, 0);
}

Передаёт каждый кластер графем в str в заданный блок или возвращает итератор, если блок не задан. В отличие от String#each_char, этот итератор перебирает кластеры графем, определённые Приложением #29 к стандарту Unicode unicode.org/reports/tr29/

"a\u0300".each_char.to_a.size #=> 2
"a\u0300".each_grapheme_cluster.to_a.size #=> 1
each_line(separator=$/, chomp: false) {|substr| block } → str Показать исходный код
each_line(separator=$/, chomp: false) → an_enumerator
static VALUE
rb_str_each_line(int argc, VALUE *argv, VALUE str)
{
    RETURN_SIZED_ENUMERATOR(str, argc, argv, 0);
    return rb_str_enumerate_lines(argc, argv, str, 0);
}

Разделяет str с использованием указанного разделителя строк (по умолчанию `/`), передавая каждую подстроку в блок. Если разделитель имеет длину ноль, строка разбивается на абзацы, разделённые несколькими последовательными символами новой строки.

Если chomp равно true, separator будет удалён с конца каждой строки.

Если блок не задан, вместо этого возвращается итератор.

"hello\nworld".each_line {|s| p s}
# prints:
#   "hello\n"
#   "world"

"hello\nworld".each_line('l') {|s| p s}
# prints:
#   "hel"
#   "l"
#   "o\nworl"
#   "d"

"hello\n\n\nworld".each_line('') {|s| p s}
# prints
#   "hello\n\n"
#   "world"

"hello\nworld".each_line(chomp: true) {|s| p s}
# prints:
#   "hello"
#   "world"

"hello\nworld".each_line('l', chomp: true) {|s| p s}
# prints:
#   "he"
#   ""
#   "o\nwor"
#   "d"
empty? → true or false Показать исходный код
static VALUE
rb_str_empty(VALUE str)
{
    if (RSTRING_LEN(str) == 0)
        return Qtrue;
    return Qfalse;
}

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

"hello".empty? # => false
" ".empty? # => false
"".empty? # => true
encode(encoding, **options) → str Показать исходный код
encode(dst_encoding, src_encoding, **options) → str
encode(**options) → str
static VALUE
str_encode(int argc, VALUE *argv, VALUE str)
{
    VALUE newstr = str;
    int encidx = str_transcode(argc, argv, &newstr);
    return encoded_dup(newstr, str, encidx);
}

Первый вариант возвращает копию str, преобразованную в кодировку encoding. Второй вариант возвращает копию str, преобразованную из кодировки src_encoding в dst_encoding. Последний вариант возвращает копию str, преобразованную в Encoding.default_internal.

По умолчанию, первый и второй варианты генерируют исключение Encoding::UndefinedConversionError для символов, не определённых в целевой кодировке, и Encoding::InvalidByteSequenceError для недопустимых последовательностей байтов в исходной кодировке. Последний вариант по умолчанию не генерирует исключений, а использует строки замены.

Ключевые аргументы options предоставляют подробности преобразования. Аргументы:

:invalid

Если значение равно :replace, encode заменяет недопустимые последовательности байтов в str символом замены. По умолчанию генерируется исключение Encoding::InvalidByteSequenceError

:undef

Если значение равно :replace, encode заменяет символы, которые не определены в целевой кодировке, символом замены. По умолчанию генерируется исключение Encoding::UndefinedConversionError.

:replace

Устанавливает строку замены на указанное значение. Строка замены по умолчанию — “uFFFD” для форм кодирования Unicode и “?” в противном случае.

:fallback

Устанавливает строку замены с помощью данного объекта для неопределённого символа. Объект должен быть Hash, Proc, Method или объектом, имеющим метод []. Его ключ — неопределённый символ, закодированный в исходной кодировке текущего преобразователя. Его значение может быть любой кодировкой, пока оно может быть преобразовано в целевую кодировку преобразователя.

:xml

Значение должно быть :text или :attr. Если значение :text, encode заменяет неопределённые символы их (верхнерегистровыми шестнадцатеричными) цифровыми ссылками на символы. '&', '<', и '>' преобразуются в “&amp;”, “&lt;”, и “&gt;”, соответственно. Если значение :attr, encode также приводит результат замены в кавычки (используя '“'), и заменяет '”' на “&quot;”.

:cr_newline

Заменяет LF (“n”) на CR (“r”), если значение — true.

:crlf_newline

Заменяет LF (“n”) на CRLF (“rn”), если значение — true.

:universal_newline

Заменяет CRLF (“rn”) и CR (“r”) на LF (“n”), если значение — true.

encode!(encoding, **options) → str Показать исходный код
encode!(dst_encoding, src_encoding, **options) → str
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);
}

Первый вариант преобразует содержимое str из str.encoding в encoding. Второй вариант преобразует содержимое str из src_encoding в dst_encoding. Ключевые аргументы options предоставляют подробности преобразования. Подробности см. в String#encode. Возвращает строку, даже если изменений не было.

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?([suffixes]+) → true or false Показать исходный код
static VALUE
rb_str_end_with(int argc, VALUE *argv, VALUE str)
{
    int i;
    char *p, *s, *e;
    rb_encoding *enc;

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

Возвращает true, если str заканчивается одной из suffixes заданных строк.

"hello".end_with?("ello")               #=> true

# returns true if one of the +suffixes+ matches.
"hello".end_with?("heaven", "ello")     #=> true
"hello".end_with?("heaven", "paradise") #=> false
eql?(object) → true or false Показать исходный код
MJIT_FUNC_EXPORTED VALUE
rb_str_eql(VALUE str1, VALUE str2)
{
    if (str1 == str2) return Qtrue;
    if (!RB_TYPE_P(str2, T_STRING)) return Qfalse;
    return rb_str_eql_internal(str1, str2);
}

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

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

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

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

Изменяет кодировку на encoding и возвращает self.

freeze() Показать исходный код
VALUE
rb_str_freeze(VALUE str)
{
    if (OBJ_FROZEN(str)) return str;
    rb_str_resize(str, RSTRING_LEN(str));
    return rb_obj_freeze(str);
}
getbyte(index) → 0 .. 255 Показать исходный код
static VALUE
rb_str_getbyte(VALUE str, VALUE index)
{
    long pos = NUM2LONG(index);

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

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

Возвращает index-й байт в виде целого числа.

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

Возвращает массив графемных кластеров в str. Это сокращение для str.each_grapheme_cluster.to_a.

Если задан блок (устаревшая форма), он работает так же, как each_grapheme_cluster.

gsub(pattern, replacement) → new_str Показать исходный код
gsub(pattern, hash) → new_str
gsub(pattern) {|match| block } → new_str
gsub(pattern) → enumerator
static VALUE
rb_str_gsub(int argc, VALUE *argv, VALUE str)
{
    return str_gsub(argc, argv, str, 0);
}

Возвращает копию str с всеми вхождениями pattern, заменёнными на второе значение. pattern обычно является Regexp; если задано как String, любые метасимволы регулярных выражений в нём будут интерпретированы буквально, например, \d будет соответствовать обратной косой черте, за которой идёт 'd', а не цифре.

Если replacement — String, он будет заменён на совпавшее значение. Он может содержать обратные ссылки на группы захвата шаблона в форме \d, где d — номер группы, или \k<n>, где n — имя группы. Аналогично, \&, \', \`, и + соответствуют специальным переменным $&, $', $`, и $+, соответственно. (См. regexp.rdoc для подробностей.) \0 эквивалентно \&. \\ интерпретируется как экранирование, т.е. как одиночная обратная косая черта. Обратите внимание, что в пределах replacement специальные переменные совпадения, такие как $&, не будут относиться к текущему совпадению.

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

В форме с блоком текущая строка совпадения передаётся в качестве параметра, и переменные, такие как $1, $2, $`, $&, и $' будут установлены соответствующим образом. (См. regexp.rdoc для подробностей.) Значение, возвращаемое блоком, будет заменено на совпадение при каждом вызове.

Когда не задан ни блок, ни второй аргумент, возвращается Enumerator.

"hello".gsub(/[aeiou]/, '*')                  #=> "h*ll*"
"hello".gsub(/([aeiou])/, '<\1>')             #=> "h<e>ll<o>"
"hello".gsub(/./) {|s| s.ord.to_s + ' '}      #=> "104 101 108 108 111 "
"hello".gsub(/(?<foo>[aeiou])/, '{\k<foo>}')  #=> "h{e}ll{o}"
'hello'.gsub(/[eo]/, 'e' => 3, 'o' => '*')    #=> "h3ll*"

Обратите внимание, что строковая литерал потребляет обратные косые черты. (См. syntax/literals.rdoc для подробностей о строковых литералах.) Обратные ссылки обычно предваряются дополнительной обратной косой чертой. Например, если вы хотите написать обратную ссылку \& в replacement со строковой литералом с двойными кавычками, вам нужно написать: "..\\&..". Если вы хотите написать строку без обратной ссылки \& в replacement, вам нужно сначала экранировать обратную косую черту, чтобы этот метод не интерпретировал её как обратную ссылку, а затем вам нужно экранировать обратные косые черты ещё раз, чтобы предотвратить потребление их строковой литералом: "..\\\\&..". Вы можете использовать форму с блоком, чтобы избежать множества обратных косых черт.

gsub!(pattern, replacement) → str or nil Показать исходный код
gsub!(pattern, hash) → str or nil
gsub!(pattern) {|match| block } → str 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);
}

Выполняет подстановки String#gsub на месте, возвращая str или nil, если подстановок не было. Если блок и replacement не заданы, возвращается перечислитель.

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

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

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

Обрабатывает ведущие символы из str как строку шестнадцатеричных цифр (с необязательным знаком и необязательным 0x) и возвращает соответствующее число. В случае ошибки возвращается ноль.

"0x0a".hex     #=> 10
"-1234".hex    #=> -4660
"0".hex        #=> 0
"wombat".hex   #=> 0
include? other_str → true or false Показать исходный код
static VALUE
rb_str_include(VALUE str, VALUE arg)
{
    long i;

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

    if (i == -1) return Qfalse;
    return Qtrue;
}

Возвращает true, если str содержит заданную строку или символ.

"hello".include? "lo"   #=> true
"hello".include? "ol"   #=> false
"hello".include? ?h     #=> true
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;
    long pos;

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

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

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

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

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

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

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

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

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

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

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

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

См. также: String#rindex

VALUE
rb_str_replace(VALUE str, VALUE str2)
{
    str_modifiable(str);
    if (str == str2) return str;

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

Заменяет содержимое str соответствующими значениями в other_str.

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

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

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

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

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

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

'foo'.insert(-2, 'bar') # => "fobaro"
inspect → string Показать исходный код
VALUE
rb_str_inspect(VALUE str)
{
    int encidx = ENCODING_GET(str);
    rb_encoding *enc = rb_enc_from_index(encidx), *actenc;
    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;
    actenc = get_actual_encoding(encidx, str);
    if (actenc != enc) {
        enc = actenc;
        if (unicode_p) unicode_p = rb_enc_unicode_p(enc);
    }
    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;
        }
        if ((enc == resenc && rb_enc_isprint(c, enc)) ||
            (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;
}

Возвращает печатный вид str в кавычках, со спецсимволами, экранированными.

str = "hello"
str[3] = "\b"
str.inspect       #=> "\"hel\\bo\""
intern → symbol Показать исходный код
VALUE
rb_str_intern(VALUE str)
{
    VALUE sym;
#if USE_SYMBOL_GC
    rb_encoding *enc, *ascii;
    int type;
#else
    ID id;
#endif
    GLOBAL_SYMBOLS_ENTER(symbols);
    {
        sym = lookup_str_sym_with_lock(symbols, str);

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

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

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

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

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

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

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

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

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

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

String#isutf8 → true or 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 → integer Показать исходный код
VALUE
rb_str_length(VALUE str)
{
    return LONG2NUM(str_strlen(str, NULL));
}

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

"\x80\u3042".length # => 2
"hello".length # => 5

String#size — алиас для String#length.

См. также: String#bytesize.

Также алиас: size
lines(separator=$/, chomp: false) → an_array Показать исходный код
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);
}

Возвращает массив строк из str, разделённых заданным разделителем записей ($/ по умолчанию). Это сокращение для str.each_line(separator, getline_args).to_a.

Если chomp равно true, separator будет удалено с конца каждой строки.

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

Если задан блок (устаревшая форма), работает так же, как each_line.

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

Если integer больше длины str, возвращает новую String длины integer, с str, выровненной влево, и заполненной padstr; в противном случае возвращает str.

"hello".ljust(4)            #=> "hello"
"hello".ljust(20)           #=> "hello               "
"hello".ljust(20, '1234')   #=> "hello123412341234123"
lstrip → new_str Показать исходный код
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);
}

Возвращает копию объекта-приёмника с удалёнными начальными пробелами. См. также String#rstrip и String#strip.

Обратитесь к String#strip для определения пробелов.

"  hello  ".lstrip   #=> "hello  "
"hello".lstrip       #=> "hello"
lstrip! → self or 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);
#if !SHARABLE_MIDDLE_SUBSTRING
        TERM_FILL(start+len, rb_enc_mbminlen(enc));
#endif
        return str;
    }
    return Qnil;
}

Удаляет начальные пробельные символы из получателя. Возвращает изменённый получатель или nil , если изменений не было. См. также String#rstrip! и String#strip!.

Обратитесь к String#strip для определения пробельных символов.

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

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

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

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

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

    matchdata = <tt>regexp.match(self)

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

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

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

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

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

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

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

Примечание: не обновляет глобальные переменные, связанные с регулярными выражениями.

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

regexp = Regexp.new(pattern)

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

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

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

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

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

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

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

Преемник цифры — это другая цифра, «переносящая» в следующий слева символ при «переполнении» от 9 до 0 и добавляющая другую цифру при необходимости:

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

Преемник буквы — это другая буква того же регистра, переходящая к следующему слева символу при переполнении и добавляющая другую букву того же регистра при необходимости:

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

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

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

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

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

Преемник пустой строки — это новая пустая строка:

''.succ # => ""

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

Псевдоним для: succ

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

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

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

Обрабатывает ведущие символы str как строку восьмеричных цифр (с необязательным знаком) и возвращает соответствующее число. Возвращает 0, если преобразование не выполнено.

"123".oct       #=> 83
"-377".oct      #=> -255
"bad".oct       #=> 0
"0377bad".oct   #=> 255

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

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

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

Возвращает Integer порядковый номер символьной строки длиной в один символ.

"a".ord         #=> 97
partition(sep) → [head, sep, tail] Показать исходный код
partition(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));
}

Ищет sep или шаблон (regexp) в строке и возвращает часть перед ним, совпадение и часть после него. Если не найдено, возвращает две пустые строки и str.

"hello".partition("l")         #=> ["he", "l", "lo"]
"hello".partition("x")         #=> ["hello", "", ""]
"hello".partition(/.l/)        #=> ["h", "el", "lo"]
prepend(*other_strings) → str Показать исходный код
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:

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

Связанные функции: String#concat.

replace(other_str) → str

Заменяет содержимое str соответствующими значениями в other_str.

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

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

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

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

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

    return rev;
}

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

"stressed".reverse   #=> "desserts"
reverse! → str Показать исходный код
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;
}

Изменяет str на месте.

rindex(substring, offset = self.length) → integer or nil Показать исходный код
rindex(regexp, offset = self.length) → integer or nil
static VALUE
rb_str_rindex_m(int argc, VALUE *argv, VALUE str)
{
    VALUE sub;
    VALUE vpos;
    rb_encoding *enc = STR_ENC_GET(str);
    long pos, len = str_strlen(str, enc); /* str's enc */

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

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

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

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

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

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

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

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

string to _end_ the search:
 'foo'.rindex('o', 0) # => nil
 'foo'.rindex('o', 1) # => 1
 'foo'.rindex('o', 2) # => 2
 'foo'.rindex('o', 3) # => 2

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

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

Связанные функции: String#index

rjust(integer, padstr=' ') → new_str Показать исходный код
static VALUE
rb_str_rjust(int argc, VALUE *argv, VALUE str)
{
    return rb_str_justify(argc, argv, str, 'r');
}

Если integer больше длины str, возвращает новую String длиной integer с str, выровненной вправо и заполненной padstr; в противном случае возвращает str.

"hello".rjust(4)            #=> "hello"
"hello".rjust(20)           #=> "               hello"
"hello".rjust(20, '1234')   #=> "123412341234123hello"
rpartition(sep) → [head, sep, tail] Показать исходный код
rpartition(regexp) → [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;
        }
        pos = rb_str_offset(str, pos);
    }

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

Ищет sep или шаблон (regexp) в строке с конца строки и возвращает часть перед ним, совпадение и часть после него. Если не найдено, возвращает две пустые строки и str.

"hello".rpartition("l")         #=> ["hel", "l", "o"]
"hello".rpartition("x")         #=> ["", "", "hello"]
"hello".rpartition(/.l/)        #=> ["he", "ll", "o"]
rstrip → new_str Показать исходный код
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);
}

Возвращает копию получателя с удалёнными пробелами в конце. См. также String#lstrip и String#strip.

Обратитесь к String#strip для определения пробелов.

"  hello  ".rstrip   #=> "  hello"
"hello".rstrip       #=> "hello"
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);
#if !SHARABLE_MIDDLE_SUBSTRING
        TERM_FILL(start+len, rb_enc_mbminlen(enc));
#endif
        return str;
    }
    return Qnil;
}

Удаляет пробелы в конце получателя. Возвращает изменённый получатель или nil если изменений не было. См. также String#lstrip! и String#strip!.

Обратитесь к String#strip для определения пробелов.

"  hello  ".rstrip!  #=> "  hello"
"  hello".rstrip!    #=> nil
"hello".rstrip!      #=> nil
scan(pattern) → array Показать исходный код
scan(pattern) {|match, ...| block } → str
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;
}

В обоих формах итерация по str, сопоставляя шаблон (который может быть Regexp или String). Для каждого совпадения генерируется результат, который либо добавляется в массив результатов, либо передаётся в блок. Если шаблон не содержит групп, каждый отдельный результат состоит из сопоставленной строки, $&. Если шаблон содержит группы, каждый отдельный результат сам по себе является массивом, содержащим по одному элементу на группу.

a = "cruel world"
a.scan(/\w+/)        #=> ["cruel", "world"]
a.scan(/.../)        #=> ["cru", "el ", "wor"]
a.scan(/(...)/)      #=> [["cru"], ["el "], ["wor"]]
a.scan(/(..)(..)/)   #=> [["cr", "ue"], ["l ", "wo"]]

А вот и форма с блоком:

a.scan(/\w+/) {|w| print "<<#{w}>> " }
print "\n"
a.scan(/(.)(.)/) {|x,y| print y, x }
print "\n"

выводит:

<<cruel>> <<world>>
rceu lowlr
scrub → new_str Показать исходный код
scrub(repl) → new_str
scrub{|bytes|} → new_str
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. Если задан блок, заменяет некорректные байты возвращаемым значением блока.

"abc\u3042\x81".scrub #=> "abc\u3042\uFFFD"
"abc\u3042\x81".scrub("*") #=> "abc\u3042*"
"abc\u3042\xE3\x80".scrub{|bytes| '<'+bytes.unpack('H*')[0]+'>' } #=> "abc\u3042<e380>"
scrub! → str Показать исходный код
scrub!(repl) → str
scrub!{|bytes|} → str
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;
}

Если в строке некорректная последовательность байтов, то заменяет некорректные байты заданным символом замены, в противном случае возвращает self. Если задан блок, заменяет некорректные байты возвращаемым значением блока.

"abc\u3042\x81".scrub! #=> "abc\u3042\uFFFD"
"abc\u3042\x81".scrub!("*") #=> "abc\u3042*"
"abc\u3042\xE3\x80".scrub!{|bytes| '<'+bytes.unpack('H*')[0]+'>' } #=> "abc\u3042<e380>"
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 *head, *left = 0;
    unsigned char *ptr;
    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));
    unsigned char byte = NUM2INT(w) & 0xFF;

    if (!str_independent(str))
        str_make_independent(str);
    enc = STR_ENC_GET(str);
    head = RSTRING_PTR(str);
    ptr = (unsigned char *)&head[pos];
    if (!STR_EMBED_P(str)) {
        cr = ENC_CODERANGE(str);
        switch (cr) {
          case ENC_CODERANGE_7BIT:
            left = (char *)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.

shellescape → string Показать исходный код
# File lib/shellwords.rb, line 224
def shellescape
  Shellwords.escape(self)
end

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

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

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

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

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

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

"\x80\u3042".length # => 2
"hello".length # => 5

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

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

Псевдоним для: length

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

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

'bar'[2] # => "r"

Счётчик идёт назад от конца self если index отрицателен:

'foo'[-3] # => "f"

Возвращает nil если index выходит за пределы диапазона:

'foo'[3] # => nil
'foo'[-4] # => nil

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

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

Счётчик идёт назад от конца self если start отрицателен:

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

Специальный случай: возвращает новую пустую строку, если start равно длине self:

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

Возвращает nil если start выходит за пределы диапазона:

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

Возвращает заключительную подстроку self если length большое:

'foo'[1, 50] # => "oo"

Возвращает nil если length отрицательно:

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

Когда указан единственный диапазон range, вычисляет значения start и length из заданного range, и возвращает значения, как указано выше:

  • 'foo'[0..1] эквивалентно 'foo'[0, 2].

  • 'foo'[0...1] эквивалентно 'foo'[0, 1].

Когда в качестве аргумента указан Regexp regexp, а аргумент capture равен 0, возвращает первую найденную сопоставляющую подстроку в self, или nil если не найдено:

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

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

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"

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

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

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

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

Псевдоним для: []
slice!(integer) → new_str or nil Показать исходный код
slice!(integer, integer) → new_str or nil
slice!(range) → new_str or nil
slice!(regexp) → new_str or nil
slice!(other_str) → new_str 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;
}

Удаляет указанную часть из str и возвращает удалённую часть.

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(pattern=nil, [limit]) → an_array Показать исходный код
split(pattern=nil, [limit]) {|sub| block } → str
static VALUE
rb_str_split_m(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    VALUE spat;
    VALUE limit;
    split_type_t split_type;
    long beg, end, i = 0, empty_count = -1;
    int lim = 0;
    VALUE result, tmp;

    result = rb_block_given_p() ? Qfalse : Qnil;
    if (rb_scan_args(argc, argv, "02", &spat, &limit) == 2) {
        lim = NUM2INT(limit);
        if (lim <= 0) limit = Qnil;
        else if (lim == 1) {
            if (RSTRING_LEN(str) == 0)
                return result ? rb_ary_new2(0) : str;
            tmp = str_duplicate(rb_cString, str);
            if (!result) {
                rb_yield(tmp);
                return str;
            }
            return rb_ary_new3(1, tmp);
        }
        i = 1;
    }
    if (NIL_P(limit) && !lim) empty_count = 0;

    enc = STR_ENC_GET(str);
    split_type = SPLIT_TYPE_REGEXP;
    if (!NIL_P(spat)) {
        spat = get_pat_quoted(spat, 0);
    }
    else if (NIL_P(spat = rb_fs)) {
        split_type = SPLIT_TYPE_AWK;
    }
    else if (!(spat = rb_fs_check(spat))) {
        rb_raise(rb_eTypeError, "value of $; must be String or Regexp");
    }
    else {
        rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "$; is set to non-nil value");
    }
    if (split_type != SPLIT_TYPE_AWK) {
        switch (BUILTIN_TYPE(spat)) {
          case T_REGEXP:
            rb_reg_options(spat); /* check if uninitialized */
            tmp = RREGEXP_SRC(spat);
            split_type = literal_split_pattern(tmp, SPLIT_TYPE_REGEXP);
            if (split_type == SPLIT_TYPE_AWK) {
                spat = tmp;
                split_type = SPLIT_TYPE_STRING;
            }
            break;

          case T_STRING:
            mustnot_broken(spat);
            split_type = literal_split_pattern(spat, SPLIT_TYPE_STRING);
            break;

          default:
            UNREACHABLE_RETURN(Qnil);
        }
    }

#define SPLIT_STR(beg, len) (empty_count = split_string(result, str, beg, len, empty_count))

    if (result) result = rb_ary_new();
    beg = 0;
    char *ptr = RSTRING_PTR(str);
    char *eptr = RSTRING_END(str);
    if (split_type == SPLIT_TYPE_AWK) {
        char *bptr = ptr;
        int skip = 1;
        unsigned int c;

        end = beg;
        if (is_ascii_string(str)) {
            while (ptr < eptr) {
                c = (unsigned char)*ptr++;
                if (skip) {
                    if (ascii_isspace(c)) {
                        beg = ptr - bptr;
                    }
                    else {
                        end = ptr - bptr;
                        skip = 0;
                        if (!NIL_P(limit) && lim <= i) break;
                    }
                }
                else if (ascii_isspace(c)) {
                    SPLIT_STR(beg, end-beg);
                    skip = 1;
                    beg = ptr - bptr;
                    if (!NIL_P(limit)) ++i;
                }
                else {
                    end = ptr - bptr;
                }
            }
        }
        else {
            while (ptr < eptr) {
                int n;

                c = rb_enc_codepoint_len(ptr, eptr, &n, enc);
                ptr += n;
                if (skip) {
                    if (rb_isspace(c)) {
                        beg = ptr - bptr;
                    }
                    else {
                        end = ptr - bptr;
                        skip = 0;
                        if (!NIL_P(limit) && lim <= i) break;
                    }
                }
                else if (rb_isspace(c)) {
                    SPLIT_STR(beg, end-beg);
                    skip = 1;
                    beg = ptr - bptr;
                    if (!NIL_P(limit)) ++i;
                }
                else {
                    end = ptr - bptr;
                }
            }
        }
    }
    else if (split_type == SPLIT_TYPE_STRING) {
        char *str_start = ptr;
        char *substr_start = ptr;
        char *sptr = RSTRING_PTR(spat);
        long slen = RSTRING_LEN(spat);

        mustnot_broken(str);
        enc = rb_enc_check(str, spat);
        while (ptr < eptr &&
               (end = rb_memsearch(sptr, slen, ptr, eptr - ptr, enc)) >= 0) {
            /* Check we are at the start of a char */
            char *t = rb_enc_right_char_head(ptr, ptr + end, eptr, enc);
            if (t != ptr + end) {
                ptr = t;
                continue;
            }
            SPLIT_STR(substr_start - str_start, (ptr+end) - substr_start);
            ptr += end + slen;
            substr_start = ptr;
            if (!NIL_P(limit) && lim <= ++i) break;
        }
        beg = ptr - str_start;
    }
    else if (split_type == SPLIT_TYPE_CHARS) {
        char *str_start = ptr;
        int n;

        mustnot_broken(str);
        enc = rb_enc_get(str);
        while (ptr < eptr &&
               (n = rb_enc_precise_mbclen(ptr, eptr, enc)) > 0) {
            SPLIT_STR(ptr - str_start, n);
            ptr += n;
            if (!NIL_P(limit) && lim <= ++i) break;
        }
        beg = ptr - str_start;
    }
    else {
        long len = RSTRING_LEN(str);
        long start = beg;
        long idx;
        int last_null = 0;
        struct re_registers *regs;
        VALUE match = 0;

        for (; rb_reg_search(spat, str, start, 0) >= 0;
             (match ? (rb_match_unbusy(match), rb_backref_set(match)) : (void)0)) {
            match = rb_backref_get();
            if (!result) rb_match_busy(match);
            regs = RMATCH_REGS(match);
            end = BEG(0);
            if (start == end && BEG(0) == END(0)) {
                if (!ptr) {
                    SPLIT_STR(0, 0);
                    break;
                }
                else if (last_null == 1) {
                    SPLIT_STR(beg, rb_enc_fast_mbclen(ptr+beg, eptr, enc));
                    beg = start;
                }
                else {
                    if (start == len)
                        start++;
                    else
                        start += rb_enc_fast_mbclen(ptr+start,eptr,enc);
                    last_null = 1;
                    continue;
                }
            }
            else {
                SPLIT_STR(beg, end-beg);
                beg = start = END(0);
            }
            last_null = 0;

            for (idx=1; idx < regs->num_regs; idx++) {
                if (BEG(idx) == -1) continue;
                SPLIT_STR(BEG(idx), END(idx)-BEG(idx));
            }
            if (!NIL_P(limit) && lim <= ++i) break;
        }
        if (match) rb_match_unbusy(match);
    }
    if (RSTRING_LEN(str) > 0 && (!NIL_P(limit) || RSTRING_LEN(str) > beg || lim < 0)) {
        SPLIT_STR(beg, RSTRING_LEN(str)-beg);
    }

    return result ? result : str;
}

Разделяет строку str на подстроки на основе разделителя, возвращая массив этих подстрок.

Если pattern является String, его содержимое используется в качестве разделителя при разделении str. Если pattern — это один пробел, str разделяется по пробелам, при этом ведущие и хвостовые пробелы, а также серии последовательных пробелов игнорируются.

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

Если pattern равно nil, используется значение $;. Если $; равно nil (что является значением по умолчанию), str разделяется по пробелам, как если бы был указан ' '.

Если параметр limit опущен, хвостовые нулевые поля подавляются. Если limit — положительное число, будет возвращено не более этого числа разделительных подстрок (захваченные группы также будут возвращены, но не учитываются при подсчете лимита). Если limit равно 1, вся строка возвращается как единственный элемент в массиве. Если отрицательное, нет ограничения на количество возвращаемых полей, и хвостовые нулевые поля не подавляются.

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

" now's  the time ".split       #=> ["now's", "the", "time"]
" now's  the time ".split(' ')  #=> ["now's", "the", "time"]
" now's  the time".split(/ /)   #=> ["", "now's", "", "the", "time"]
"1, 2.34,56, 7".split(%r{,\s*}) #=> ["1", "2.34", "56", "7"]
"hello".split(//)               #=> ["h", "e", "l", "l", "o"]
"hello".split(//, 3)            #=> ["h", "e", "llo"]
"hi mom".split(%r{\s*})         #=> ["h", "i", "m", "o", "m"]

"mellow yellow".split("ello")   #=> ["m", "w y", "w"]
"1,2,,3,4,,".split(',')         #=> ["1", "2", "", "3", "4"]
"1,2,,3,4,,".split(',', 4)      #=> ["1", "2", "", "3,4,,"]
"1,2,,3,4,,".split(',', -4)     #=> ["1", "2", "", "3", "4", "", ""]

"1:2:3".split(/(:)()()/, 2)     #=> ["1", ":", "", "", "2:3"]

"".split(',', -1)               #=> []

Если задан блок, вызывается блок с каждой разделенной подстрокой.

squeeze([other_str]*) → new_str Показать исходный код
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;
}

Строит множество символов из параметра(ов) other_str, используя процедуру, описанную для String#count. Возвращает новую строку, где последовательности одинаковых символов, которые входят в это множество, заменяются одним символом. Если аргументы не заданы, все последовательности одинаковых символов заменяются одним символом.

"yellow moon".squeeze                  #=> "yelow mon"
"  now   is  the".squeeze(" ")         #=> " now is the"
"putters shoot balls".squeeze("m-z")   #=> "puters shot balls"
squeeze!([other_str]*) → str 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;
}

Сжимает str на месте, возвращая либо str, либо nil если никаких изменений не было.

start_with?([prefixes]+) → true or false Показать исходный код
static VALUE
rb_str_start_with(int argc, VALUE *argv, VALUE str)
{
    int i;

    for (i=0; i<argc; i++) {
        VALUE tmp = argv[i];
        if (RB_TYPE_P(tmp, T_REGEXP)) {
            if (rb_reg_start_with_p(tmp, str))
                return Qtrue;
        }
        else {
            StringValue(tmp);
            rb_enc_check(str, tmp);
            if (RSTRING_LEN(str) < RSTRING_LEN(tmp)) continue;
            if (memcmp(RSTRING_PTR(str), RSTRING_PTR(tmp), RSTRING_LEN(tmp)) == 0)
                return Qtrue;
        }
    }
    return Qfalse;
}

Возвращает true, если str начинается с одного из prefixes заданных. Каждый из prefixes должен быть String или Regexp.

"hello".start_with?("hell")               #=> true
"hello".start_with?(/H/i)                 #=> true

# returns true if one of the prefixes matches.
"hello".start_with?("heaven", "hell")     #=> true
"hello".start_with?("heaven", "paradise") #=> false
strip → new_str Показать исходный код
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);
}

Возвращает копию объекта-получателя со удаленными начальными и конечными пробелами.

Пробелы определяются как любой из следующих символов: null, табуляция, перевод строки, вертикальная табуляция, символ перевода страницы, возврат каретки, пробел.

"    hello    ".strip   #=> "hello"
"\tgoodbye\r\n".strip   #=> "goodbye"
"\x00\t\n\v\f\r ".strip #=> ""
"hello".strip           #=> "hello"
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);
#if !SHARABLE_MIDDLE_SUBSTRING
        TERM_FILL(start+len, rb_enc_mbminlen(enc));
#endif
        return str;
    }
    return Qnil;
}

Удаляет начальные и конечные пробелы из объекта-получателя. Возвращает изменённый объект-получатель, или nil если изменений не было.

Обратитесь к String#strip для определения пробелов.

"  hello  ".strip!  #=> "hello"
"hello".strip!      #=> nil
sub(pattern, replacement) → new_str Показать исходный код
sub(pattern, hash) → new_str
sub(pattern) {|match| block } → new_str
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;
}

Возвращает копию str с заменой первого вхождения pattern вторым аргументом. Второй аргумент обычно является Regexp; если он задан как String, все метасимволы регулярных выражений в нём будут интерпретироваться буквально, например \d будет соответствовать обратной косой черте, за которой следует 'd', а не цифре.

Если второй аргумент — String, он подставляется вместо совпавшей строки. Он может содержать обратные ссылки на группы захвата шаблона в виде \d, где d — номер группы, или \k<n>, где n — имя группы. Аналогично, \&, \', \`, и + соответствуют специальным переменным, $&, $', $`, и $+, соответственно. (См. regexp.rdoc для подробностей.) \0 такое же, как \&. \\ интерпретируется как escape, т.е. как одиночная обратная косая черта. Обратите внимание, что внутри replacement специальные переменные совпадений, такие как $&, не будут ссылаться на текущее совпадение.

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

В блочной форме текущая строка совпадения передается в качестве параметра, и переменные, такие как $1, $2, $`, $&, и $' будут установлены соответствующим образом. (См. regexp.rdoc для подробностей.) Значение, возвращаемое блоком, будет подставлено для совпадения на каждом вызове.

"hello".sub(/[aeiou]/, '*')                  #=> "h*llo"
"hello".sub(/([aeiou])/, '<\1>')             #=> "h<e>llo"
"hello".sub(/./) {|s| s.ord.to_s + ' ' }     #=> "104 ello"
"hello".sub(/(?<foo>[aeiou])/, '*\k<foo>*')  #=> "h*e*llo"
'Is SHELL your preferred shell?'.sub(/[[:upper:]]{2,}/, ENV)
 #=> "Is /bin/bash your preferred shell?"

Обратите внимание, что строковая литерал потребляет обратные косые черты. (См. syntax/literals.rdoc для получения подробностей о строковых литералах.) Обратные ссылки обычно предваряются дополнительной обратной косой чертой. Например, если вы хотите написать обратную ссылку \& в replacement со строковой литералом с двойными кавычками, вам нужно написать: "..\\&..". Если вы хотите написать строку без обратной ссылки \& в replacement, вам сначала нужно экранировать обратную косую черту, чтобы предотвратить интерпретацию метода её как обратной ссылки, а затем вам нужно экранировать обратные косые черты ещё раз, чтобы предотвратить потребление строковой литералом: "..\\\\&..". Вы можете использовать блочную форму, чтобы избежать большого количества обратных косых черт.

sub!(pattern, replacement) → str or nil Показать исходный код
sub!(pattern) {|match| block } → str or nil
static VALUE
rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
{
    VALUE pat, repl, hash = Qnil;
    int iter = 0;
    long plen;
    int min_arity = rb_block_given_p() ? 1 : 2;
    long beg;

    rb_check_arity(argc, min_arity, 2);
    if (argc == 1) {
        iter = 1;
    }
    else {
        repl = argv[1];
        hash = rb_check_hash_type(argv[1]);
        if (NIL_P(hash)) {
            StringValue(repl);
        }
    }

    pat = get_pat_quoted(argv[0], 1);

    str_modifiable(str);
    beg = rb_pat_search(pat, str, 0, 1);
    if (beg >= 0) {
        rb_encoding *enc;
        int cr = ENC_CODERANGE(str);
        long beg0, end0;
        VALUE match, match0 = Qnil;
        struct re_registers *regs;
        char *p, *rp;
        long len, rlen;

        match = rb_backref_get();
        regs = RMATCH_REGS(match);
        if (RB_TYPE_P(pat, T_STRING)) {
            beg0 = beg;
            end0 = beg0 + RSTRING_LEN(pat);
            match0 = pat;
        }
        else {
            beg0 = BEG(0);
            end0 = END(0);
            if (iter) match0 = rb_reg_nth_match(0, match);
        }

        if (iter || !NIL_P(hash)) {
            p = RSTRING_PTR(str); len = RSTRING_LEN(str);

            if (iter) {
                repl = rb_obj_as_string(rb_yield(match0));
            }
            else {
                repl = rb_hash_aref(hash, rb_str_subseq(str, beg0, end0 - beg0));
                repl = rb_obj_as_string(repl);
            }
            str_mod_check(str, p, len);
            rb_check_frozen(str);
        }
        else {
            repl = rb_reg_regsub(repl, str, regs, RB_TYPE_P(pat, T_STRING) ? Qnil : pat);
        }

        enc = rb_enc_compatible(str, repl);
        if (!enc) {
            rb_encoding *str_enc = STR_ENC_GET(str);
            p = RSTRING_PTR(str); len = RSTRING_LEN(str);
            if (coderange_scan(p, beg0, str_enc) != ENC_CODERANGE_7BIT ||
                coderange_scan(p+end0, len-end0, str_enc) != ENC_CODERANGE_7BIT) {
                rb_raise(rb_eEncCompatError, "incompatible character encodings: %s and %s",
                         rb_enc_name(str_enc),
                         rb_enc_name(STR_ENC_GET(repl)));
            }
            enc = STR_ENC_GET(repl);
        }
        rb_str_modify(str);
        rb_enc_associate(str, enc);
        if (ENC_CODERANGE_UNKNOWN < cr && cr < ENC_CODERANGE_BROKEN) {
            int cr2 = ENC_CODERANGE(repl);
            if (cr2 == ENC_CODERANGE_BROKEN ||
                (cr == ENC_CODERANGE_VALID && cr2 == ENC_CODERANGE_7BIT))
                cr = ENC_CODERANGE_UNKNOWN;
            else
                cr = cr2;
        }
        plen = end0 - beg0;
        rlen = RSTRING_LEN(repl);
        len = RSTRING_LEN(str);
        if (rlen > plen) {
            RESIZE_CAPA(str, len + rlen - plen);
        }
        p = RSTRING_PTR(str);
        if (rlen != plen) {
            memmove(p + beg0 + rlen, p + beg0 + plen, len - beg0 - plen);
        }
        rp = RSTRING_PTR(repl);
        memmove(p + beg0, rp, rlen);
        len += rlen - plen;
        STR_SET_LEN(str, len);
        TERM_FILL(&RSTRING_PTR(str)[len], TERM_LEN(str));
        ENC_CODERANGE_SET(str, cr);

        return str;
    }
    return Qnil;
}

Выполняет ту же подстановку, что и String#sub, на месте.

Возвращает str если подстановка была выполнена или nil если подстановка не была выполнена.

succ → new_str Показать исходный код
VALUE
rb_str_succ(VALUE orig)
{
    VALUE str;
    str = rb_str_new(RSTRING_PTR(orig), RSTRING_LEN(orig));
    rb_enc_cr_str_copy_for_substr(str, orig);
    return str_succ(str);
}

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

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

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

Преемник цифры — это другая цифра, «переносящая» в следующий слева символ для «переполнения» от 9 до 0 и вставляющая новую цифру, если необходимо:

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

Преемник буквы — это другая буква той же буквы, переносимая в следующий слева символ для переполнения, и вставляющая новую букву той же буквы, если необходимо:

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

Преемник небуквенно-цифрового символа — это следующий символ в порядке сортировки базового набора символов, переносящийся в следующий слева символ для переполнения и вставляющий новый символ, если необходимо:

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

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

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

Преемник пустой строки — это новая пустая строка:

''.succ # => ""

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

Также алиас: next
succ! → self Показать исходный код
static VALUE
rb_str_succ_bang(VALUE str)
{
    rb_str_modify(str);
    str_succ(str);
    return str;
}

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

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

Также алиас: next!
sum(n=16) → 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 битов символов в str, где n — необязательный параметр Integer, по умолчанию равный 16. Результат — просто сумма двоичных значений каждого байта в str по модулю 2**n - 1. Это не очень хорошая контрольная сумма.

swapcase → new_str Показать исходный код
swapcase([options]) → new_str
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;
}

Возвращает копию str, в которой заглавные буквы латинского алфавита заменены на строчные, а строчные — на заглавные.

См. String#downcase для значения options и использования с различными кодировками.

"Hello".swapcase          #=> "hELLO"
"cYbEr_PuNk11".swapcase   #=> "CyBeR_pUnK11"
swapcase! → str or nil Показать исходный код
swapcase!([options]) → str 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;
}

Эквивалентно String#swapcase, но изменяет получатель на месте, возвращая str или nil , если изменений не произошло.

См. String#downcase для значения options и использования с различными кодировками.

to_c → complex Показать исходный код
static VALUE
string_to_c(VALUE self)
{
    char *s;
    VALUE num;

    rb_must_asciicompat(self);

    s = RSTRING_PTR(self);

    if (s && s[RSTRING_LEN(self)]) {
        rb_str_modify(self);
        s = RSTRING_PTR(self);
        s[RSTRING_LEN(self)] = '\0';
    }

    if (!s)
        s = (char *)"";

    (void)parse_comp(s, 0, &num);

    return num;
}

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

'9'.to_c           #=> (9+0i)
'2.5'.to_c         #=> (2.5+0i)
'2.5/1'.to_c       #=> ((5/2)+0i)
'-3/2'.to_c        #=> ((-3/2)+0i)
'-i'.to_c          #=> (0-1i)
'45i'.to_c         #=> (0+45i)
'3-4i'.to_c        #=> (3-4i)
'-4e2-4e-2i'.to_c  #=> (-400.0-0.04i)
'-0.0-0.0i'.to_c   #=> (-0.0-0.0i)
'1/2+3/4i'.to_c    #=> ((1/2)+(3/4)*i)
'ruby'.to_c        #=> (0+0i)

См. Kernel.Complex.

to_d → bigdecimal Показать исходный код
# File ext/bigdecimal/lib/bigdecimal/util.rb, line 68
def to_d
  BigDecimal.interpret_loosely(self)
end

Возвращает результат интерпретации начальных символов в str как BigDecimal.

require 'bigdecimal'
require 'bigdecimal/util'

"0.5".to_d             # => 0.5e0
"123.45e1".to_d        # => 0.12345e4
"45.67 degrees".to_d   # => 0.4567e2

См. также BigDecimal::new.

to_f → float Показать исходный код
static VALUE
rb_str_to_f(VALUE str)
{
    return DBL2NUM(rb_str_to_dbl(str, FALSE));
}

Возвращает результат интерпретации начальных символов в str как число с плавающей точкой. Дополнительные символы после окончания допустимого числа игнорируются. Если в начале str нет допустимого числа, возвращается 0.0. Этот метод никогда не вызывает исключение.

"123.45e1".to_f        #=> 1234.5
"45.67 degrees".to_f   #=> 45.67
"thx1138".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);
}

Возвращает результат интерпретации начальных символов в str как целое число по основанию base (от 2 до 36). Дополнительные символы после окончания допустимого числа игнорируются. Если в начале str нет допустимого числа, возвращается 0. Этот метод никогда не вызывает исключение, когда base допустимо.

"12345".to_i             #=> 12345
"99 red balloons".to_i   #=> 99
"0a".to_i                #=> 0
"0a".to_i(16)            #=> 10
"hello".to_i             #=> 0
"1100101".to_i(2)        #=> 101
"1100101".to_i(8)        #=> 294977
"1100101".to_i(10)       #=> 1100101
"1100101".to_i(16)       #=> 17826049
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 → str Показать исходный код
static VALUE
rb_str_to_s(VALUE str)
{
    if (rb_obj_class(str) != rb_cString) {
        return str_duplicate(rb_cString, str);
    }
    return str;
}

Возвращает self.

Если вызывается на подклассе String, преобразует получатель в объект String.

Также алиасировано как: to_str

Возвращает self.

Если вызывается на подклассе String, преобразует получатель в объект String.

Псевдоним для: 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(from_str, to_str) → new_str Показать исходный код
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;
}

Возвращает копию str с символами из from_str , заменёнными соответствующими символами в to_str. Если to_str короче from_str, он дополняется своим последним символом, чтобы сохранить соответствие.

"hello".tr('el', 'ip')      #=> "hippo"
"hello".tr('aeiou', '*')    #=> "h*ll*"
"hello".tr('aeiou', 'AA*')  #=> "hAll*"

Обе строки могут использовать c1-c2 нотацию для обозначения диапазонов символов, и from_str может начинаться с ^, что обозначает все символы, кроме перечисленных.

"hello".tr('a-y', 'b-z')    #=> "ifmmp"
"hello".tr('^aeiou', '*')   #=> "*e**o"

Символ обратного слэша \ может использоваться для экранирования ^ или - и в противном случае игнорируется, если он не появляется в конце диапазона или в конце from_str или to_str.

"hello^world".tr("\\^aeiou", "*") #=> "h*ll**w*rld"
"hello-world".tr("a\\-eo", "*")   #=> "h*ll**w*rld"

"hello\r\nworld".tr("\r", "")   #=> "hello\nworld"
"hello\r\nworld".tr("\\r", "")  #=> "hello\r\nwold"
"hello\r\nworld".tr("\\\r", "") #=> "hello\nworld"

"X['\\b']".tr("X\\", "")   #=> "['b']"
"X['\\b']".tr("X-\\]", "") #=> "'b'"
tr!(from_str, to_str) → str or nil Показать исходный код
static VALUE
rb_str_tr_bang(VALUE str, VALUE src, VALUE repl)
{
    return tr_trans(str, src, repl, 0);
}

Перевод str на месте, используя те же правила, что и String#tr. Возвращает str или nil , если изменений не произошло.

END_OF_DOCUMENT_MARKER
tr_s(from_str, to_str) → new_str Показать исходный код
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;
}

Обрабатывает копию str, как описано в String#tr, затем удаляет повторяющиеся символы в регионах, которые были затронуты переводом.

"hello".tr_s('l', 'r')     #=> "hero"
"hello".tr_s('el', '*')    #=> "h*o"
"hello".tr_s('el', 'hx')   #=> "hhxo"
tr_s!(from_str, to_str) → str 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 над str на месте, возвращая str или nil, если изменений не было.

undump → new_str Показать исходный код
static VALUE
str_undump(VALUE str)
{
    const char *s = RSTRING_PTR(str);
    const char *s_end = RSTRING_END(str);
    rb_encoding *enc = rb_enc_get(str);
    VALUE undumped = rb_enc_str_new(s, 0L, enc);
    bool utf8 = false;
    bool binary = false;
    int w;

    rb_must_asciicompat(str);
    if (rb_str_is_ascii_only_p(str) == Qfalse) {
        rb_raise(rb_eRuntimeError, "non-ASCII character detected");
    }
    if (!str_null_check(str, &w)) {
        rb_raise(rb_eRuntimeError, "string contains null byte");
    }
    if (RSTRING_LEN(str) < 2) goto invalid_format;
    if (*s != '"') goto invalid_format;

    /* strip '"' at the start */
    s++;

    for (;;) {
        if (s >= s_end) {
            rb_raise(rb_eRuntimeError, "unterminated dumped string");
        }

        if (*s == '"') {
            /* epilogue */
            s++;
            if (s == s_end) {
                /* ascii compatible dumped string */
                break;
            }
            else {
                static const char force_encoding_suffix[] = ".force_encoding(\""; /* "\")" */
                static const char dup_suffix[] = ".dup";
                const char *encname;
                int encidx;
                ptrdiff_t size;

                /* check separately for strings dumped by older versions */
                size = sizeof(dup_suffix) - 1;
                if (s_end - s > size && memcmp(s, dup_suffix, size) == 0) s += size;

                size = sizeof(force_encoding_suffix) - 1;
                if (s_end - s <= size) goto invalid_format;
                if (memcmp(s, force_encoding_suffix, size) != 0) goto invalid_format;
                s += size;

                if (utf8) {
                    rb_raise(rb_eRuntimeError, "dumped string contained Unicode escape but used force_encoding");
                }

                encname = s;
                s = memchr(s, '"', s_end-s);
                size = s - encname;
                if (!s) goto invalid_format;
                if (s_end - s != 2) goto invalid_format;
                if (s[0] != '"' || s[1] != ')') goto invalid_format;

                encidx = rb_enc_find_index2(encname, (long)size);
                if (encidx < 0) {
                    rb_raise(rb_eRuntimeError, "dumped string has unknown encoding name");
                }
                rb_enc_associate_index(undumped, encidx);
            }
            break;
        }

        if (*s == '\\') {
            s++;
            if (s >= s_end) {
                rb_raise(rb_eRuntimeError, "invalid escape");
            }
            undump_after_backslash(undumped, &s, s_end, &enc, &utf8, &binary);
        }
        else {
            rb_str_cat(undumped, s++, 1);
        }
    }

    return undumped;
invalid_format:
    rb_raise(rb_eRuntimeError, "invalid dumped string; not wrapped with '\"' nor '\"...\".force_encoding(\"...\")' form");
}

Возвращает неэкранированную версию строки. Это обратная операция к String#dump.

"\"hello \\n ''\"".undump #=> "hello \n ''"
unicode_normalize(form=:nfc) Показать исходный код
static VALUE
rb_str_unicode_normalize(int argc, VALUE *argv, VALUE str)
{
    return unicode_normalize_common(argc, argv, str, id_normalize);
}

Нормализация Unicode — возвращает нормализованную форму str, используя Unicode-нормализации NFC, NFD, NFKC или NFKD. Используемая форма нормализации определяется form, которое может принимать любое из четырёх значений :nfc, :nfd, :nfkc, или :nfkd. По умолчанию используется :nfc.

Если строка не в формате Unicode Encoding, то генерируется исключение Exception. В данном контексте 'кодировка Unicode' подразумевает UTF-8, UTF-16BE/LE, UTF-32BE/LE, а также GB18030, UCS_2BE и UCS_4BE. Любой формат кроме UTF-8 реализуется путём преобразования в UTF-8, что делает его медленнее, чем UTF-8.

"a\u0300".unicode_normalize        #=> "\u00E0"
"a\u0300".unicode_normalize(:nfc)  #=> "\u00E0"
"\u00E0".unicode_normalize(:nfd)   #=> "a\u0300"
"\xE0".force_encoding('ISO-8859-1').unicode_normalize(:nfd)
                                   #=> Encoding::CompatibilityError raised
unicode_normalize!(form=:nfc) Показать исходный код
static VALUE
rb_str_unicode_normalize_bang(int argc, VALUE *argv, VALUE str)
{
    return rb_str_replace(str, unicode_normalize_common(argc, argv, str, id_normalize));
}

Деструктивная версия String#unicode_normalize, выполняющая нормализацию Unicode на месте.

unicode_normalized?(form=:nfc) Показать исходный код
static VALUE
rb_str_unicode_normalized_p(int argc, VALUE *argv, VALUE str)
{
    return unicode_normalize_common(argc, argv, str, id_normalized_p);
}

Проверяет, находится ли str в форме Unicode-нормализации form, которая может принимать любое из четырёх значений :nfc, :nfd, :nfkc, или :nfkd. По умолчанию используется :nfc.

Если строка не в формате Unicode Encoding, то генерируется исключение Exception. Подробнее см. String#unicode_normalize.

"a\u0300".unicode_normalized?        #=> false
"a\u0300".unicode_normalized?(:nfd)  #=> true
"\u00E0".unicode_normalized?         #=> true
"\u00E0".unicode_normalized?(:nfd)   #=> false
"\xE0".force_encoding('ISO-8859-1').unicode_normalized?
                                     #=> Encoding::CompatibilityError raised
unpack(format) → anArray Показать исходный код
# File pack.rb, line 256
def unpack(fmt)
  Primitive.pack_unpack(fmt)
end

Декодирует str (которое может содержать двоичные данные) в соответствии с строкой формата, возвращая массив из каждого извлечённого значения. Строка формата состоит из последовательности символьных директив, суммированных в таблице в конце этой записи. Каждая директива может быть после-довательностями с числом, указывающим количество повторов этой директивы. Звёздочка («*'') использует все оставшиеся элементы. Директивы sSiIlL могут быть после-довательностями с подчёркиванием («_'') или восклицательным знаком («!'') для использования родного размера платформы для указанного типа; в противном случае используется независимый от платформы размер. Пробелы в строке формата игнорируются. См. также String#unpack1, Array#pack.

"abc \0\0abc \0\0".unpack('A6Z6')   #=> ["abc", "abc "]
"abc \0\0".unpack('a3a3')           #=> ["abc", " \000\000"]
"abc \0abc \0".unpack('Z*Z*')       #=> ["abc ", "abc "]
"aa".unpack('b8B8')                 #=> ["10000110", "01100001"]
"aaa".unpack('h2H2c')               #=> ["16", "61", 97]
"\xfe\xff\xfe\xff".unpack('sS')     #=> [-2, 65534]
"now=20is".unpack('M*')             #=> ["now is"]
"whole".unpack('xax2aX2aX1aX2a')    #=> ["h", "e", "l", "l", "o"]

В этой таблице суммируются различные форматы и Ruby классы, возвращаемые каждым из них.

Integer       |         |
Directive     | Returns | Meaning
------------------------------------------------------------------
C             | Integer | 8-bit unsigned (unsigned char)
S             | Integer | 16-bit unsigned, native endian (uint16_t)
L             | Integer | 32-bit unsigned, native endian (uint32_t)
Q             | Integer | 64-bit unsigned, native endian (uint64_t)
J             | Integer | pointer width unsigned, native endian (uintptr_t)
              |         |
c             | Integer | 8-bit signed (signed char)
s             | Integer | 16-bit signed, native endian (int16_t)
l             | Integer | 32-bit signed, native endian (int32_t)
q             | Integer | 64-bit signed, native endian (int64_t)
j             | Integer | pointer width signed, native endian (intptr_t)
              |         |
S_ S!         | Integer | unsigned short, native endian
I I_ I!       | Integer | unsigned int, native endian
L_ L!         | Integer | unsigned long, native endian
Q_ Q!         | Integer | unsigned long long, native endian (ArgumentError
              |         | if the platform has no long long type.)
J!            | Integer | uintptr_t, native endian (same with J)
              |         |
s_ s!         | Integer | signed short, native endian
i i_ i!       | Integer | signed int, native endian
l_ l!         | Integer | signed long, native endian
q_ q!         | Integer | signed long long, native endian (ArgumentError
              |         | if the platform has no long long type.)
j!            | Integer | intptr_t, native endian (same with j)
              |         |
S> s> S!> s!> | Integer | same as the directives without ">" except
L> l> L!> l!> |         | big endian
I!> i!>       |         |
Q> q> Q!> q!> |         | "S>" is same as "n"
J> j> J!> j!> |         | "L>" is same as "N"
              |         |
S< s< S!< s!< | Integer | same as the directives without "<" except
L< l< L!< l!< |         | little endian
I!< i!<       |         |
Q< q< Q!< q!< |         | "S<" is same as "v"
J< j< J!< j!< |         | "L<" is same as "V"
              |         |
n             | Integer | 16-bit unsigned, network (big-endian) byte order
N             | Integer | 32-bit unsigned, network (big-endian) byte order
v             | Integer | 16-bit unsigned, VAX (little-endian) byte order
V             | Integer | 32-bit unsigned, VAX (little-endian) byte order
              |         |
U             | Integer | UTF-8 character
w             | Integer | BER-compressed integer (see Array#pack)

Float        |         |
Directive    | Returns | Meaning
-----------------------------------------------------------------
D d          | Float   | double-precision, native format
F f          | Float   | single-precision, native format
E            | Float   | double-precision, little-endian byte order
e            | Float   | single-precision, little-endian byte order
G            | Float   | double-precision, network (big-endian) byte order
g            | Float   | single-precision, network (big-endian) byte order

String       |         |
Directive    | Returns | Meaning
-----------------------------------------------------------------
A            | String  | arbitrary binary string (remove trailing nulls and ASCII spaces)
a            | String  | arbitrary binary string
Z            | String  | null-terminated string
B            | String  | bit string (MSB first)
b            | String  | bit string (LSB first)
H            | String  | hex string (high nibble first)
h            | String  | hex string (low nibble first)
u            | String  | UU-encoded string
M            | String  | quoted-printable, MIME encoding (see RFC2045)
m            | String  | base64 encoded string (RFC 2045) (default)
             |         | base64 encoded string (RFC 4648) if followed by 0
P            | String  | pointer to a structure (fixed-length string)
p            | String  | pointer to a null-terminated string

Misc.        |         |
Directive    | Returns | Meaning
-----------------------------------------------------------------
@            | ---     | skip to the offset given by the length argument
X            | ---     | skip backward one byte
x            | ---     | skip forward one byte

ИСТОРИЯ

  • J, J! j, и j! доступны с Ruby 2.3.

  • Q_, Q!, q_, и q! доступны с Ruby 2.1.

  • I!<, i!<, I!>, и i!> доступны с Ruby 1.9.3.

unpack1(format) → obj Показать исходный код
# File pack.rb, line 280
def unpack1(fmt)
  Primitive.pack_unpack1(fmt)
end

Декодирует str (которое может содержать двоичные данные) в соответствии с строкой формата, возвращая первое извлечённое значение. См. также String#unpack, Array#pack.

Противопоставление String#unpack:

"abc \0\0abc \0\0".unpack('A6Z6')   #=> ["abc", "abc "]
"abc \0\0abc \0\0".unpack1('A6Z6')  #=> "abc"

В этом случае данные будут утеряны, но часто бывает так, что массив содержит только одно значение, особенно при распаковке двоичных данных. Например:

“xffx00x00x00”.unpack(“l”) #=> [255] “xffx00x00x00”.unpack1(“l”) #=> 255

Таким образом, unpack1 удобно, делает ясным намерение и сигнализирует ожидаемое возвращаемое значение тем, кто читает код.

upcase → new_str Показать исходный код
upcase([options]) → new_str
static VALUE
rb_str_upcase(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    OnigCaseFoldType flags = ONIGENC_CASE_UPCASE;
    VALUE ret;

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

    return ret;
}

Возвращает копию str, где все строчные буквы заменены на прописные.

См. String#downcase для значения options и использования с различными кодировками.

"hEllO".upcase   #=> "HELLO"
upcase! → str or nil Показать исходный код
upcase!([options]) → str or nil
static VALUE
rb_str_upcase_bang(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    OnigCaseFoldType flags = ONIGENC_CASE_UPCASE;

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

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

Преобразует содержимое str в верхний регистр, возвращая nil если изменений не было.

См. String#downcase для значения options и использования с различными кодировками.

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 }

Без блока возвращает новый Enumerator:

'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 cr == ENC_CODERANGE_BROKEN ? Qfalse : Qtrue;
}

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

"\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–2020 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API