非常教程

Ruby 2.4参考手册

字符串 | String

String

Parent:ObjectIncluded modules:Comparable

BigDecimal扩展了本地的String类以提供to_d方法。

当您在应用程序中需要BigDecimal时,此方法将在String对象上可用。

一个String对象拥有并操纵任意字节序列,通常表示字符。字符串对象可以使用String::new或作为文字创建。

由于别名问题,字符串用户应该知道修改String对象内容的方法。通常,名称以“!”结尾的方法修改接收者,而没有“!”的方法返回新的String。但是,也有例外,如String#[]=

公共实例方法

String#iseuc → true or false Show source

返回self编码是否为EUC-JP。

# File ext/nkf/lib/kconv.rb, line 263
def iseuc;    Kconv.iseuc(self) end

String#isjis → true or false Show source

返回self编码是否为ISO-2022-JP。

# File ext/nkf/lib/kconv.rb, line 275
def isjis;    Kconv.isjis(self) end

String#issjis → true or false Show source

Returns whether self's encoding is Shift_JIS or not.

# File ext/nkf/lib/kconv.rb, line 269
def issjis;   Kconv.issjis(self) end

String#isutf8 → true or false Show source

返回self编码是否为UTF-8。

# File ext/nkf/lib/kconv.rb, line 281
def isutf8;   Kconv.isutf8(self) end

String#kconv(to_enc, from_enc) Show source

转换selfto_encto_encfrom_enc作为Kconv或Encoding对象的常量给出。

# File ext/nkf/lib/kconv.rb, line 204
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

to_c → complex Show source

返回一个表示字符串形式的复合体。解析器忽略前导空白和尾随垃圾。任何数字序列都可以用下划线分隔。为null或垃圾字符串返回零。

'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。

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;
}

to_d → bigdecimal Show source

转换string为BigDecimal并返回。

require 'bigdecimal'
require 'bigdecimal/util'

"0.5".to_d
# => 0.5e0
# File ext/bigdecimal/lib/bigdecimal/util.rb, line 59
def to_d
  BigDecimal(self)
end

String#toeuc → string Show source

转换self为EUC-JP

# File ext/nkf/lib/kconv.rb, line 223
def toeuc; Kconv.toeuc(self) end

String#tojis → string Show source

转换self为ISO-2022-JP

# File ext/nkf/lib/kconv.rb, line 217
def tojis; Kconv.tojis(self) end

String#tolocale → string Show source

转换self为区域设置编码

# File ext/nkf/lib/kconv.rb, line 253
def tolocale; Kconv.tolocale(self) end

String#tosjis → string Show source

转换self为Shift_JIS

# File ext/nkf/lib/kconv.rb, line 229
def tosjis; Kconv.tosjis(self) end

String#toutf16 → string Show source

转换self为UTF-16

# File ext/nkf/lib/kconv.rb, line 241
def toutf16; Kconv.toutf16(self) end

String#toutf32 → string Show source

转换self为UTF-32

# File ext/nkf/lib/kconv.rb, line 247
def toutf32; Kconv.toutf32(self) end

String#toutf8 → string Show source

转换self为UTF-8

# File ext/nkf/lib/kconv.rb, line 235
def toutf8; Kconv.toutf8(self) end

scanf

↑ top

公共类方法

new(str="") → new_str Show source

new(str="", encoding: enc) → new_str

new(str="", capacity: size) → new_str

返回包含str副本的新字符串对象。

可选的enc参数指定新字符串的编码。如果未指定,则使用str(或ASCII-8BIT,如果未指定str)的编码。

可选的size参数指定内部缓冲区的大小。这可能会提高性能,当字符串将被连接多次(并调用很多realloc)。

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 */
                RSTRING(str)->as.heap.ptr = ALLOC_N(char, (size_t)capa + termlen);
            }
            else if (STR_HEAP_SIZE(str) != (size_t)capa + termlen) {
                REALLOC_N(RSTRING(str)->as.heap.ptr, char, (size_t)capa + termlen);
            }
            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;
}

try_convert(obj) → string or nil Show source

尝试使用#to_str方法将obj转换为字符串。如果obj由于任何原因无法转换,则返回转换后的字符串或nil 。

String.try_convert("str")     #=> "str"
String.try_convert(/re/)      #=> nil
static VALUE
rb_str_s_try_convert(VALUE dummy, VALUE str)
{
    return rb_check_string_type(str);
}

公共实例方法

str % arg → new_str Show source

格式 - 使用str作为格式规范,并返回将其应用于arg的结果。如果格式规范包含多个替换,则arg必须是Array或者Hash包含要替换的值。请参阅Kernel::sprintf格式字符串的详细信息。

"%05d" % 123                              #=> "00123"
"%-5s: %08x" % [ "ID", self.object_id ]   #=> "ID   : 200e14d6"
"foo = %{foo}" % { :foo => 'bar' }        #=> "foo = bar"
static VALUE
rb_str_format_m(VALUE str, VALUE arg)
{
    VALUE tmp = rb_check_array_type(arg);

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

str * integer → new_str Show source

复制 - 返回包含integer接收器副本的新字符串。integer必须大于或等于0。

"Ho! " * 3   #=> "Ho! Ho! Ho! "
"Ho! " * 0   #=> ""
VALUE
rb_str_times(VALUE str, VALUE times)
{
    VALUE str2;
    long n, len;
    char *ptr2;
    int termlen;

    if (times == INT2FIX(1)) {
        return rb_str_dup(str);
    }
    if (times == INT2FIX(0)) {
        str2 = str_alloc(rb_obj_class(str));
        rb_enc_copy(str2, str);
        OBJ_INFECT(str2, str);
        return str2;
    }
    len = NUM2LONG(times);
    if (len < 0) {
        rb_raise(rb_eArgError, "negative argument");
    }
    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_obj_class(str), 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);
    OBJ_INFECT(str2, str);
    rb_enc_cr_str_copy_for_substr(str2, str);

    return str2;
}

str + other_str → new_str Show source

连接 - 返回一个新的String包含连接到str的other_str

"Hello from " + self.to_s   #=> "Hello from main"
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);

    FL_SET_RAW(str3, OBJ_TAINTED_RAW(str1) | OBJ_TAINTED_RAW(str2));
    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;
}

+str → str (mutable) Show source

如果字符串被冻结,则返回重复的可变字符串。

如果字符串未被冻结,则返回字符串本身。

static VALUE
str_uplus(VALUE str)
{
    if (OBJ_FROZEN(str)) {
        return rb_str_dup(str);
    }
    else {
        return str;
    }
}

-str → str (frozen) Show source

如果字符串被冻结,则返回字符串本身。

如果字符串没有被冻结,那么复制该字符串将其冻结并返回。

static VALUE
str_uminus(VALUE str)
{
    if (OBJ_FROZEN(str)) {
        return str;
    }
    else {
        return rb_str_freeze(rb_str_dup(str));
    }
}

str << integer → str Show source

concat(integer1, integer2,...) → str

str << obj → str

concat(obj1, obj2,...) → str

追加 - 将给定的对象连接到str。如果对象是an Integer,则它被视为代码点,并在连接之前转换为字符。Concat可以有多个参数。所有参数按顺序连接。

a = "hello "
a << "world"   #=> "hello world"
a.concat(33)   #=> "hello world!"
a              #=> "hello world!"

b = "sn"
b.concat(b, b)    #=> "snsnsn"
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;
}

string <=> other_string → -1, 0, +1 or nil Show source

比较返回-1,0,+1或零,具体取决于是否string小于,等于或大于other_string

nil 如果两个值无法比较,则返回。

如果琴弦长度不同,并且琴弦在比较长度最短时相等,则较长的琴弦被认为大于较短的琴弦。

<=>对于方法的基础<<=>>=,和between?,从模块可比包括在内。方法String#==不使用Comparable#==。

"abcdef" <=> "abcde"     #=> 1
"abcdef" <=> "abcdef"    #=> 0
"abcdef" <=> "abcdefg"   #=> -1
"abcdef" <=> "ABCDEF"    #=> 1
"abcdef" <=> 1           #=> nil
static VALUE
rb_str_cmp_m(VALUE str1, VALUE str2)
{
    int result;

    if (!RB_TYPE_P(str2, T_STRING)) {
        VALUE tmp = rb_check_funcall(str2, idTo_str, 0, 0);
        if (RB_TYPE_P(tmp, T_STRING)) {
            result = rb_str_cmp(str1, tmp);
        }
        else {
            return rb_invcmp(str1, str2);
        }
    }
    else {
        result = rb_str_cmp(str1, str2);
    }
    return INT2FIX(result);
}

str == obj → true or false Show source

Equality-Returns是否str== obj,类似于Object#==。

如果obj不是字符串的一个实例但响应to_str,则使用两个字符串进行比较obj.==

否则,与#eql?类似地返回,比较长度和内容。

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 str_eql(str1, str2);
}

str === obj → true or false Show source

Equality-Returns是否str== obj,类似于Object#==。

如果obj不是字符串的一个实例但响应to_str,则使用两个字符串进行比较obj.==

否则,与#eql?类似地返回,比较长度和内容。

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 str_eql(str1, str2);
}

str =~ obj → integer or nil Show source

匹配 - 如果obj是a Regexp,则将其用作匹配str的模式,并返回匹配开始的位置,或者nil如果不匹配。否则,调用obj。=〜,将str作为参数传递。默认=~Object收益nil

注意:str =~ regexp不一样regexp =~ str。从命名捕获组捕获的字符串仅在第二种情况下才分配给局部变量。

"cat o' 9 tails" =~ /\d/   #=> 7
"cat o' 9 tails" =~ 9      #=> nil
static VALUE
rb_str_match(VALUE x, VALUE y)
{
    if (SPECIAL_CONST_P(y)) goto generic;
    switch (BUILTIN_TYPE(y)) {
      case T_STRING:
        rb_raise(rb_eTypeError, "type mismatch: String given");

      case T_REGEXP:
        return rb_reg_match(y, x);

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

strindex → new_str or nil Show source

strstart, length → new_str or nil

strrange → new_str or nil

strregexp → new_str or nil

strregexp, capture → new_str or nil

strmatch_str → new_str or nil

元素引用 - 如果传递单个元素index,则返回该索引处的一个字符的子字符串。如果传递一个start索引,并且length返回一个包含lengthstart索引开始的字符的子字符串。如果传递了a range,则它的开始和结束被解释为定义要返回的子字符串的偏移量。

在这三种情况下,如果索引是负数,则从字符串的末尾开始计数。对于startrange案件的起始索引仅仅是一个性格和匹配字符串的大小的指标之前。此外,如果字符范围的起始索引位于字符串的末尾,则会返回空字符串。

返回nil如果初始索引落在串外侧或长度为负。

如果Regexp提供了a ,则返回该字符串的匹配部分。如果capture遵循正则表达式(可能是捕获组索引或名称),则遵循正则表达式,而是返回MatchData的组件。

如果match_str给出a,则返回该字符串,如果它出现在字符串中。

nil如果正则表达式不匹配或无法找到匹配字符串,则返回。

a = "hello there"

a[1]                   #=> "e"
a[2, 3]                #=> "llo"
a[2..3]                #=> "ll"

a[-3, 2]               #=> "er"
a[7..-2]               #=> "her"
a[-4..-2]              #=> "her"
a[-2..-4]              #=> ""

a[11, 0]               #=> ""
a[11]                  #=> nil
a[12, 0]               #=> nil
a[12..-1]              #=> nil

a[/[aeiou](.)\1/]      #=> "ell"
a[/[aeiou](.)\1/, 0]   #=> "ell"
a[/[aeiou](.)\1/, 1]   #=> "l"
a[/[aeiou](.)\1/, 2]   #=> nil

a[/(?<vowel>[aeiou])(?<non_vowel>[^aeiou])/, "non_vowel"] #=> "l"
a[/(?<vowel>[aeiou])(?<non_vowel>[^aeiou])/, "vowel"]     #=> "e"

a["lo"]                #=> "lo"
a["bye"]               #=> 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]);
}

strinteger = new_str Show source

strinteger, integer = new_str

strrange = aString

strregexp = new_str

strregexp, integer = new_str

strregexp, name = new_str

strother_str = new_str

Element Assignment—Replaces some or all of the content of str. The portion of the string affected is determined using the same criteria as String#[]. If the replacement string is not the same length as the text it is replacing, the string will be adjusted accordingly. If the regular expression or string is used as the index doesn't match a position in the string, IndexError is raised. If the regular expression form is used, the optional second Integer allows you to specify which portion of the match to replace (effectively using the MatchData indexing rules. The forms that take an Integer will raise an IndexError if the value is out of range; the Range form will raise a RangeError, and the Regexp and String will raise an IndexError on negative match.

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]);
}

ascii_only? → true or false Show source

对于只有ASCII字符的字符串返回true。

"abc".force_encoding("UTF-8").ascii_only?          #=> true
"abc\u{6666}".force_encoding("UTF-8").ascii_only?  #=> 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;
}

b → str Show source

返回编码为ASCII-8BIT的复制字符串。

static VALUE
rb_str_b(VALUE str)
{
    VALUE str2 = str_alloc(rb_cString);
    str_replace_shared_without_enc(str2, str);
    OBJ_INFECT_RAW(str2, str);
    ENC_CODERANGE_CLEAR(str2);
    return str2;
}

block_scanf(fstr) { |current_match| ... } Show source

扫描当前字符串,直到匹配耗尽为止,在字符串中遇到每个匹配。块不是必需的,因为结果将被简单地聚合到最终数组中。

"123 456".block_scanf("%d")
# => [123, 456]

如果给出了块,则从yield返回的值将被添加到输出数组中。

"123 456".block_scanf("%d) do |digit,| # the ',' unpacks the Array
  digit + 100
end
# => [223, 556]

有关创建格式字符串的详细信息,请参阅Scanf。

你将需要'scanf'来使用#block_scanf

# File lib/scanf.rb, line 752
def block_scanf(fstr) #:yield: current_match
  fs = Scanf::FormatString.new(fstr)
  str = self.dup
  final = []
  begin
    current = str.scanf(fs)
    final.push(yield(current)) unless current.empty?
    str = fs.string_left
  end until current.empty? || str.empty?
  return final
end

bytes → an_array Show source

返回str中的字节数组。这是一个简写str.each_byte.to_a

如果给出了一个块,这是一个不赞成使用的形式,与each_byte。相同。

static VALUE
rb_str_bytes(VALUE str)
{
    return rb_str_enumerate_bytes(str, 1);
}

bytesize → integer Show source

返回str以字节为单位的长度。

"\x80\u3042".bytesize  #=> 4
"hello".bytesize       #=> 5
static VALUE
rb_str_bytesize(VALUE str)
{
    return LONG2NUM(RSTRING_LEN(str));
}

byteslice(integer) → new_str or nil Show source

byteslice(integer, integer) → new_str or nil

byteslice(range) → new_str or nil

字节引用 - 如果传递Integer一个字符,则返回该位置一个字节的子字符串。如果传递两个Integer对象,则返回一个从第一个给定的偏移量开始的子串,第二个给出的长度。如果给定a 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"
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]);
}

capitalize → new_str Show source

capitalize(options) → new_str

返回str的一个副本,第一个字符转换为大写,其余部分转换为小写。

请参阅#downcase以了解其含义options并使用不同的编码。

"hello".capitalize    #=> "Hello"
"HELLO".capitalize    #=> "Hello"
"123ABC".capitalize   #=> "123abc"
static VALUE
rb_str_capitalize(int argc, VALUE *argv, VALUE str)
{
    str = rb_str_dup(str);
    rb_str_capitalize_bang(argc, argv, str);
    return str;
}

capitalize! → str or nil Show source

capitalize!(options) → str or nil

通过将第一个字符转换为大写字母并将其余字符转换为小写字符来修改strnil如果没有更改,则返回。

请参阅#downcase以了解其含义options并使用不同的编码。

a = "hello"
a.capitalize!   #=> "Hello"
a               #=> "Hello"
a.capitalize!   #=> 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_ENC_GET(str);
    rb_str_check_dummy_enc(enc);
    if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return Qnil;
    if (flags&ONIGENC_CASE_ASCII_ONLY)
        rb_str_ascii_casemap(str, &flags, enc);
    else
        str_shared_replace(str, rb_str_casemap(str, &flags, enc));

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

casecmp(other_str) → -1, 0, +1 or nil Show source

不区分大小写的版本String#<=>。目前,不区分大小写仅适用于字符AZ / az,而不是全部Unicode。这不同于casecmp?

"abcdef".casecmp("abcde")     #=> 1
"aBcDeF".casecmp("abcdef")    #=> 0
"abcdef".casecmp("abcdefg")   #=> -1
"abcdef".casecmp("ABCDEF")    #=> 0
static VALUE
rb_str_casecmp(VALUE str1, VALUE str2)
{
    long len;
    rb_encoding *enc;
    char *p1, *p1end, *p2, *p2end;

    StringValue(str2);
    enc = rb_enc_compatible(str1, str2);
    if (!enc) {
        return Qnil;
    }

    p1 = RSTRING_PTR(str1); p1end = RSTRING_END(str1);
    p2 = RSTRING_PTR(str2); p2end = RSTRING_END(str2);
    if (single_byte_optimizable(str1) && single_byte_optimizable(str2)) {
        while (p1 < p1end && p2 < p2end) {
            if (*p1 != *p2) {
                unsigned int c1 = TOUPPER(*p1 & 0xff);
                unsigned int c2 = TOUPPER(*p2 & 0xff);
                if (c1 != c2)
                    return INT2FIX(c1 < c2 ? -1 : 1);
            }
            p1++;
            p2++;
        }
    }
    else {
        while (p1 < p1end && p2 < p2end) {
            int l1, c1 = rb_enc_ascget(p1, p1end, &l1, enc);
            int l2, c2 = rb_enc_ascget(p2, p2end, &l2, enc);

            if (0 <= c1 && 0 <= c2) {
                c1 = TOUPPER(c1);
                c2 = TOUPPER(c2);
                if (c1 != c2)
                    return INT2FIX(c1 < c2 ? -1 : 1);
            }
            else {
                int r;
                l1 = rb_enc_mbclen(p1, p1end, enc);
                l2 = rb_enc_mbclen(p2, p2end, enc);
                len = l1 < l2 ? l1 : l2;
                r = memcmp(p1, p2, len);
                if (r != 0)
                    return INT2FIX(r < 0 ? -1 : 1);
                if (l1 != l2)
                    return INT2FIX(l1 < l2 ? -1 : 1);
            }
            p1 += l1;
            p2 += l2;
        }
    }
    if (RSTRING_LEN(str1) == RSTRING_LEN(str2)) return INT2FIX(0);
    if (RSTRING_LEN(str1) > RSTRING_LEN(str2)) return INT2FIX(1);
    return INT2FIX(-1);
}

casecmp?(other_str) → true, false, or nil Show source

如果str和other_other_str在Unicode大小写折叠后相等,则返回true;如果不相等,则返回false;如果other_str不是字符串,则返回nil。

"abcdef".casecmp?("abcde")     #=> false
"aBcDeF".casecmp?("abcdef")    #=> true
"abcdef".casecmp?("abcdefg")   #=> false
"abcdef".casecmp?("ABCDEF")    #=> true
"\u{e4 f6 fc}".casecmp?("\u{c4 d6 dc}") #=> true
static VALUE
rb_str_casecmp_p(VALUE str1, VALUE str2)
{
    rb_encoding *enc;
    VALUE folded_str1, folded_str2;
    VALUE fold_opt = sym_fold;

    StringValue(str2);
    enc = rb_enc_compatible(str1, str2);
    if (!enc) {
        return Qnil;
    }

    folded_str1 = rb_str_downcase(1, &fold_opt, str1);
    folded_str2 = rb_str_downcase(1, &fold_opt, str2);

    return rb_str_eql(folded_str1, folded_str2);
}

center(width, padstr=' ') → new_str Show source

中心strwidth。如果width大于长度str,则返回一个widthstr居中和填充长度的新String padstr; 否则,返回str

"hello".center(4)         #=> "hello"
"hello".center(20)        #=> "       hello        "
"hello".center(20, '123') #=> "1231231hello12312312"
static VALUE
rb_str_center(int argc, VALUE *argv, VALUE str)
{
    return rb_str_justify(argc, argv, str, 'c');
}

chars → an_array Show source

返回str中的一个字符数组。这是一个简写str.each_char.to_a

如果给出了一个块,这是一个不赞成使用的形式,与each_char。相同。

static VALUE
rb_str_chars(VALUE str)
{
    return rb_str_enumerate_chars(str, 1);
}

chomp(separator=$/) → new_str Show source

Stringstr结尾删除给定的记录分隔符(如果存在)返回新的。如果$/没有从默认的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"
static VALUE
rb_str_chomp(int argc, VALUE *argv, VALUE str)
{
    VALUE rs = chomp_rs(argc, argv);
    if (NIL_P(rs)) return rb_str_dup(str);
    return rb_str_subseq(str, 0, chompped_length(str, rs));
}

chomp!(separator=$/) → str or nil Show source

按照描述对str进行修改String#chomp,返回str或者nil没有进行修改。

static VALUE
rb_str_chomp_bang(int argc, VALUE *argv, VALUE str)
{
    VALUE rs;
    str_modify_keep_cr(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);
}

chop → new_str Show source

返回一个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       #=> ""
static VALUE
rb_str_chop(VALUE str)
{
    return rb_str_subseq(str, 0, chopped_length(str));
}

chop! → str or nil Show source

流程海峡作为String#chop,返回海峡,或者nil如果STR是空字符串。另见String#chomp!

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;
}

chr → string Show source

在字符串的开始处返回一个字符的字符串。

a = "abcde"
a.chr    #=> "a"
static VALUE
rb_str_chr(VALUE str)
{
    return rb_str_substr(str, 0, 1);
}

clear → string Show source

使字符串为空。

a = "abcde"
a.clear    #=> ""
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;
}

codepoints → an_array Show source

返回str中Integer字符序数组成的数组。这是一个简写。str.each_codepoint.to_a

如果给出了一个块,这是一个不赞成使用的形式,与each_codepoint。相同。

static VALUE
rb_str_codepoints(VALUE str)
{
    return rb_str_enumerate_codepoints(str, 1);
}

str << integer → str Show source

concat(integer1, integer2,...) → str

str << obj → str

concat(obj1, obj2,...) → str

追加 - 将给定的对象连接到str。如果对象是an Integer,则它被视为代码点,并在连接之前转换为字符。Concat可以有多个参数。所有参数按顺序连接。

a = "hello "
a << "world"   #=> "hello world"
a.concat(33)   #=> "hello world!"
a              #=> "hello world!"

b = "sn"
b.concat(b, b)    #=> "snsnsn"
static VALUE
rb_str_concat_multi(int argc, VALUE *argv, VALUE str)
{
    str_modifiable(str);

    if (argc > 0) {
        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;
}

count(other_str+) → integer Show source

每个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
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);
}

crypt(salt_str) → new_str Show source

通过使用给定的盐串调用标准库函数,将单向加密哈希应用于strcrypt(3)。虽然格式和结果与系统和实现相关,但\A[a-zA-Z0-9./]{2}在任何平台上使用与正则表达式匹配的salt 应该是有效且安全的,其中只有前两个字符是重要的。

此方法用于系统特定的脚本,因此如果您需要跨平台散列函数,请考虑使用Digest或OpenSSL。

static VALUE
rb_str_crypt(VALUE str, VALUE salt)
{
#ifdef HAVE_CRYPT_R
    struct crypt_data data;
#else
    extern char *crypt(const char *, const char *);
#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) {
      short_salt:
        rb_raise(rb_eArgError, "salt too short (need >=2 bytes)");
    }

    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
# ifdef HAVE_STRUCT_CRYPT_DATA_INITIALIZED
    data.initialized = 0;
# endif
    res = crypt_r(s, saltp, &data);
#else
    res = crypt(s, saltp);
#endif
    if (!res) {
        rb_sys_fail("crypt");
    }
    result = rb_str_new_cstr(res);
    FL_SET_RAW(result, OBJ_TAINTED_RAW(str) | OBJ_TAINTED_RAW(salt));
    return result;
}

delete(other_str+) → new_str Show source

返回删除其参数的交集中的所有字符的str的副本。使用与构建字符集相同的规则String#count

"hello".delete "l","lo"        #=> "heo"
"hello".delete "lo"            #=> "he"
"hello".delete "aeiou", "^e"   #=> "hell"
"hello".delete "ej-m"          #=> "ho"
static VALUE
rb_str_delete(int argc, VALUE *argv, VALUE str)
{
    str = rb_str_dup(str);
    rb_str_delete_bang(argc, argv, str);
    return str;
}

delete!(other_str+) → str or nil Show source

执行delete操作的地方,返回海峡,或者nil如果STR没有被修改。

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;
}

downcase → new_str Show source

downcase(options) → new_str

返回所有大写字母替换为小写字母的str的副本。哪些字母完全被替换,以及哪些字母取决于选项的存在与否以及encoding字符串。

其含义options如下:

没有选择

完整的Unicode大小写映射,适用于大多数语言(请参阅下面的turkic和:lithuanian选项以了解例外情况)。目前不支持Unicode标准表3-14中描述的与上下文相关的大小写映射。

:ascii

只有ASCII区域,即字符“A”到“Z”和“a”到“z”,受到影响。该选项不能与其他选项结合使用。

:turkic

完整的Unicode案例映射,适用于突厥语言(土耳其语,阿塞拜疆语,...)。这意味着大写字母I被映射为小写字母无点i,依此类推。

:lithuanian

目前,只是完整的Unicode案例映射。将来,全面的Unicode病例映射适用于立陶宛语(即使顶部有重音,小写字母也保持点状)。

:fold

仅适用于downcasedowncase!。Unicode案例折叠,这比Unicode大小写映射更加深远。这个选项目前不能与任何其他选项结合使用(也就是说,对于turkic语言,当前没有变体)。

请注意,对于仅适用于ASCII码的情况下的转换,有些假设不适用于更一般的情况转换。例如,结果的长度可能与输入的长度不相同(既不是字符也不是字节),一些往返假设(例如str.downcase == str.upcase.downcase)可能不适用,而Unicode规范化(即#unicode_normalize)不一定由大小写映射操作维护。

UTF-8,UTF-16BE / LE,UTF-32BE / LE和ISO-8859-1〜16字符串/符号目前支持非ASCII大小写映射/折叠。这种支持将扩展到其他编码。

"hEllO".downcase   #=> "hello"
static VALUE
rb_str_downcase(int argc, VALUE *argv, VALUE str)
{
    str = rb_str_dup(str);
    rb_str_downcase_bang(argc, argv, str);
    return str;
}

downcase! → str or nil Show source

downcase!(options) → str or nil

降低str的内容,nil如果没有更改则返回。

请参阅#downcase以了解其含义options并使用不同的编码。

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_ENC_GET(str);
    rb_str_check_dummy_enc(enc);
    if ((flags&ONIGENC_CASE_ASCII_ONLY) && (enc==rb_utf8_encoding() || rb_enc_mbmaxlen(enc)==1)
        || (!(flags&ONIGENC_CASE_FOLD_TURKISH_AZERI) && ENC_CODERANGE(str)==ENC_CODERANGE_7BIT)) {
        char *s = RSTRING_PTR(str), *send = RSTRING_END(str);

        while (s < send) {
            unsigned int c = *(unsigned char*)s;

            if (rb_enc_isascii(c, enc) && 'A' <= c && c <= 'Z') {
                *s = 'a' + (c - 'A');
                flags |= ONIGENC_CASE_MODIFIED;
            }
            s++;
        }
    }
    else if (flags&ONIGENC_CASE_ASCII_ONLY)
        rb_str_ascii_casemap(str, &flags, enc);
    else
        str_shared_replace(str, rb_str_casemap(str, &flags, enc));

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

dump → new_str Show source

生成一个版本,str其中所有非打印字符均由\nnn符号替换,并且所有特殊字符均已转义。

"hello \n ''".dump  #=> "\"hello \\n ''\""
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[] = ".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_with_class(str, 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();
    }
    OBJ_INFECT_RAW(result, str);
    /* result from dump is ASCII */
    rb_enc_associate_index(result, encidx);
    ENC_CODERANGE_SET(result, ENC_CODERANGE_7BIT);
    return result;
}

each_byte {|integer| block } → str Show source

each_byte → an_enumerator

str中的每个字节传递给给定的块,或者在没有给出块的情况下返回枚举器。

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

生产:

104 101 108 108 111
static VALUE
rb_str_each_byte(VALUE str)
{
    return rb_str_enumerate_bytes(str, 0);
}

each_char {|cstr| block } → str Show source

each_char → an_enumerator

str中的每个字符传递给给定的块,或者在没有给出块的情况下返回枚举器。

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

生产:

h e l l o
static VALUE
rb_str_each_char(VALUE str)
{
    return rb_str_enumerate_chars(str, 0);
}

each_codepoint {|integer| block } → str Show source

each_codepoint → an_enumerator

Integerstr中传递每个字符的序号,在将Unicode字符串应用于给定块时也称为代码点

如果没有给出块,则返回一个枚举器。

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

生产:

104 101 108 108 111 1593
static VALUE
rb_str_each_codepoint(VALUE str)
{
    return rb_str_enumerate_codepoints(str, 0);
}

each_line(separator=$/) {|substr| block } → str Show source

each_line(separator=$/) → an_enumerator

使用提供的参数将str分割为记录分隔符($/默认情况下),将每个子串依次传递给提供的块。如果提供了零长度记录分隔符,则字符串将被拆分为多个连续换行符分隔的段落。

如果没有给出块,则返回一个枚举器。

print "Example one\n"
"hello\nworld".each_line {|s| p s}
print "Example two\n"
"hello\nworld".each_line('l') {|s| p s}
print "Example three\n"
"hello\n\n\nworld".each_line('') {|s| p s}

生产:

Example one
"hello\n"
"world"
Example two
"hel"
"l"
"o\nworl"
"d"
Example three
"hello\n\n\n"
"world"
static VALUE
rb_str_each_line(int argc, VALUE *argv, VALUE str)
{
    return rb_str_enumerate_lines(argc, argv, str, 0);
}

empty? → true or false Show source

如果str的长度为零,则返回true

"hello".empty?   #=> false
" ".empty?       #=> false
"".empty?        #=> true
static VALUE
rb_str_empty(VALUE str)
{
    if (RSTRING_LEN(str) == 0)
        return Qtrue;
    return Qfalse;
}

encode(encoding , options ) → str Show source

encode(dst_encoding, src_encoding , options ) → str

encode(options) → str

第一种形式将str转码的副本返回给编码encoding。第二种形式str将从src_encoding转码的副本返回到dst_encoding。最后一个表格会将str转码后的副本返回Encoding.default_internal

默认情况下,第一种和第二种形式针对目标编码中未定义的字符引发Encoding :: UndefinedConversionError,对源编码中的无效字节序列使用Encoding :: InvalidByteSequenceError引发。默认情况下的最后一个表单不会引发异常,但使用替换字符串。

options散列给出了转换的细节,可以有以下键:

:invalid

如果值是:replace,编码用str替换字符替换无效字节序列。默认是引发Encoding :: InvalidByteSequenceError异常

:undef

如果值为:replace,则编码用替换字符替换目的地编码中未定义的字符。默认是引发Encoding :: UndefinedConversionError。

:replace

将替换字符串设置为给定值。Unicode编码形式的默认替换字符串为“uFFFD”,否则为“?”。

:fallback

将给定对象的替换字符串设置为未定义字符。该对象应该是Hash,Proc,Method或具有[]方法的对象。它的关键是在当前代码转换器的源编码中编码的未定义字符。它的值可以是任何编码,直到它可以转换为代码转换器的目标编码。

:xml

该值必须是:text:attr。如果值是:text编码,则用它们的(大写十六进制)数字字符引用替换未定义的字符。'&','<'和'>'分别被转换为“&”,“<”和“>”。如果值是:attr,则编码还引用替换结果(使用'''),并用“”替换'''。

:cr_newline

如果值为真,则用CR(“r”)替换LF(“n”)。

:crlf_newline

如果值为真,则用CRLF(“rn”)替换LF(“n”)。

:universal_newline

如果值为真,则用LF(“n”)替换CRLF(“rn”)和CR(“r”)。

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

encode!(encoding , options ) → str Show source

encode!(dst_encoding, src_encoding , options ) → str

第一种形式将str的内容从str.encoding转换为encoding。第二种形式将str的内容从src_encoding转换为dst_encoding。选项哈希提供转换的详细信息。有关详细信息,请参阅#encode。即使没有更改,也返回字符串。

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

encoding → encoding Show source

返回表示obj编码的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);
}

end_with?(suffixes+) → true or false Show source

如果strsuffixes给定的一个结束,则返回true 。

"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
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;
}

eql?(other) → true or false Show source

如果两个字符串具有相同的长度和内容,则它们是相等的。

static VALUE
rb_str_eql(VALUE str1, VALUE str2)
{
    if (str1 == str2) return Qtrue;
    if (!RB_TYPE_P(str2, T_STRING)) return Qfalse;
    return str_eql(str1, str2);
}

force_encoding(encoding) → str Show source

将编码更改为encoding并返回自我。

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;
}

freeze() Show source

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 Show source

以整数形式返回_index_th字节。

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]);
}

gsub(pattern, replacement) → new_str Show source

gsub(pattern, hash) → new_str

gsub(pattern) {|match| block } → new_str

gsub(pattern) → enumerator

返回str的一个副本,其中所有出现的模式将被替换为第二个参数。该模式通常是一个Regexp; 如果以a的String形式给出,它所包含的任何正则表达式元字符将按字面解释,例如'\\d'匹配反斜杠,后跟'd',而不是数字。

如果替换为a String,它将替换匹配的文本。它可能包含对模式的表单捕获组的反引用\\d,其中d是组号,或者\\k<n>,其中n是组名。如果它是一个双引号字符串,则两个反引用前都必须加上一个额外的反斜杠。但是,在替换中,特殊的匹配变量,如$&,不会引用当前匹配。

如果第二个参数是a Hash,并且匹配的文本是其中一个键,则相应的值是替换字符串。

在块形式中,当前匹配字符串传递作为参数,以及诸如变量$1$2$`$&,和$'将被适当地设定。该块返回的值将被替换为每次调用的匹配。

结果会继承原始字符串或任何提供的替换字符串中的任何污点。

当没有提供块和第二个参数时,返回一个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*"
static VALUE
rb_str_gsub(int argc, VALUE *argv, VALUE str)
{
    return str_gsub(argc, argv, str, 0);
}

gsub!(pattern, replacement) → str or nil Show source

gsub!(pattern, hash) → str or nil

gsub!(pattern) {|match| block } → str or nil

gsub!(pattern) → an_enumerator

执行String#gsub就地替换,返回str或者nil没有替换被执行。如果没有给出块并且没有替换,则返回一个枚举器。

static VALUE
rb_str_gsub_bang(int argc, VALUE *argv, VALUE str)
{
    str_modify_keep_cr(str);
    return str_gsub(argc, argv, str, 1);
}

hash → integer Show source

根据字符串的长度,内容和编码返回散列。

另请参阅对象#散列。

static VALUE
rb_str_hash_m(VALUE str)
{
    st_index_t hval = rb_str_hash(str);
    return ST2FIX(hval);
}

hex → integer Show source

str中的前导字符视为一串十六进制数字(带有可选符号和可选项0x)并返回相应的数字。错误返回零。

"0x0a".hex     #=> 10
"-1234".hex    #=> -4660
"0".hex        #=> 0
"wombat".hex   #=> 0
static VALUE
rb_str_hex(VALUE str)
{
    return rb_str_to_inum(str, 16, FALSE);
}

include? other_str → true or false Show source

如果str包含给定的字符串或字符,则返回true

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

index(substring , offset) → integer or nil Show source

index(regexp , offset) → integer or nil

返回str中给定子字符串或模式(regexp)的第一个匹配项的索引。如果找不到,则返回。如果第二个参数存在,它指定字符串中开始搜索的位置。nil

"hello".index('e')             #=> 1
"hello".index('lo')            #=> 3
"hello".index('a')             #=> nil
"hello".index(?e)              #=> 1
"hello".index(/[aeiou]/, -3)   #=> 4
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 (SPECIAL_CONST_P(sub)) goto generic;
    switch (BUILTIN_TYPE(sub)) {
      case 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));

        pos = rb_reg_search(sub, str, pos, 0);
        pos = rb_str_sublen(str, pos);
        break;

      generic:
      default: {
        VALUE tmp;

        tmp = rb_check_string_type(sub);
        if (NIL_P(tmp)) {
            rb_raise(rb_eTypeError, "type mismatch: %s given",
                     rb_obj_classname(sub));
        }
        sub = tmp;
      }
        /* fall through */
      case T_STRING:
        pos = rb_str_index(str, sub, pos);
        pos = rb_str_sublen(str, pos);
        break;
    }

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

replace(other_str) → str Show source

使用other_str中的相应值替换str的内容和污点

s = "hello"         #=> "hello"
s.replace "world"   #=> "world"
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);
}

insert(index, other_str) → str Show source

在给定索引的字符前插入other_str,修改str。负指数从字符串的末尾开始计数,并给定字符后面插入。意图是插入aString,以便它在给定的索引处开始。

"abcd".insert(0, 'X')    #=> "Xabcd"
"abcd".insert(3, 'X')    #=> "abcXd"
"abcd".insert(4, 'X')    #=> "abcdX"
"abcd".insert(-3, 'X')   #=> "abXcd"
"abcd".insert(-1, 'X')   #=> "abcdX"
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;
}

inspect → string Show source

返回可打印版本的str,用引号括起来特殊字符转义。

str = "hello"
str[3] = "\b"
str.inspect       #=> "\"hel\\bo\""
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, "\"");

    OBJ_INFECT_RAW(result, str);
    return result;
}

intern → symbol Show source

返回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"
VALUE
rb_str_intern(VALUE str)
{
#if USE_SYMBOL_GC
    rb_encoding *enc, *ascii;
    int type;
#else
    ID id;
#endif
    VALUE sym = lookup_str_sym(str);

    if (sym) {
	return sym;
    }

#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_new_frozen(str);
    }
    str = rb_fstring(str);
    type = rb_str_symname_type(str, IDSET_ATTRSET_FOR_INTERN);
    if (type < 0) type = ID_JUNK;
    return dsymbol_alloc(rb_cSymbol, str, enc, type);
#else
    id = intern_str(str, 0);
    return ID2SYM(id);
#endif
}

length → integer Show source

返回str的字符长度。

VALUE
rb_str_length(VALUE str)
{
    return LONG2NUM(str_strlen(str, NULL));
}

lines(separator=$/) → an_array Show source

使用提供的记录分隔符(默认情况下)返回str分割中的行数组$/。这是一个简写str.each_line(separator).to_a

如果给出了一个块,这是一个不赞成使用的形式,与each_line。相同。

static VALUE
rb_str_lines(int argc, VALUE *argv, VALUE str)
{
    return rb_str_enumerate_lines(argc, argv, str, 1);
}

ljust(integer, padstr=' ') → new_str Show source

如果整数大于str的长度,则返回一个String长度为整数的新整数,其中str为左对齐,并用padstr填充; 否则,返回str

"hello".ljust(4)            #=> "hello"
"hello".ljust(20)           #=> "hello               "
"hello".ljust(20, '1234')   #=> "hello123412341234123"
static VALUE
rb_str_ljust(int argc, VALUE *argv, VALUE str)
{
    return rb_str_justify(argc, argv, str, 'l');
}

lstrip → new_str Show source

返回删除前导空白的str的副本。另见String#rstripString#strip

请参阅strip空白的定义。

"  hello  ".lstrip   #=> "hello  "
"hello".lstrip       #=> "hello"
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 rb_str_dup(str);
    return rb_str_subseq(str, loffset, len - loffset);
}

lstrip! → self or nil Show source

str删除前导空白,nil如果没有更改则返回。另见String#rstrip!String#strip!

请参阅strip空白的定义。

"  hello  ".lstrip!  #=> "hello  "
"hello  ".lstrip!    #=> nil
"hello".lstrip!      #=> 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;
}

match(pattern) → matchdata or nil Show source

match(pattern, pos) → matchdata or nil

模式转换为Regexp(如果它不是一个),然后matchstr上调用它的方法。如果第二个参数存在,它指定字符串中开始搜索的位置。

'hello'.match('(.)\1')      #=> #<MatchData "ll" 1:"l">
'hello'.match('(.)\1')[0]   #=> "ll"
'hello'.match(/(.)\1/)[0]   #=> "ll"
'hello'.match('xx')         #=> nil

如果给出了块匹配成功,则用MatchData调用块,以便写入

str.match(pat) {|m| ...}

代替

if m = str.match(pat)
  ...
end

返回值是这种情况下块执行的值。

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;
}

match?(pattern) → true or false Show source

match?(pattern, pos) → true or false

模式转换为Regexp(如果它不是一个),然后返回a truefalse指示正则表达式是否匹配str,而不更新$~和其他相关变量。如果第二个参数存在,它指定字符串中开始搜索的位置。

"Ruby".match?(/R.../)    #=> true
"Ruby".match?(/R.../, 1) #=> false
"Ruby".match?(/P.../)    #=> false
$&                       #=> nil
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);
}

next → new_str Show source

返回str的后继者。后继者是通过从字符串中最右边的字母数字(或最右边的字符,如果没有字母数字)开始递增字符来计算的。增加一个数字总是会导致另一个数字,并且递增一个字母会导致另一个字母相同的情况。增加非字母数字使用底层字符集的整理顺序。

如果增量生成“进位”,则左侧的字符增加。这个过程重复,直到没有进位,如有必要添加一个额外的字符。

"abcd".succ        #=> "abce"
"THX1138".succ     #=> "THX1139"
"<<koala>>".succ   #=> "<<koalb>>"
"1999zzz".succ     #=> "2000aaa"
"ZZZ9999".succ     #=> "AAAA0000"
"***".succ         #=> "**+"
VALUE
rb_str_succ(VALUE orig)
{
    VALUE str;
    str = rb_str_new_with_class(orig, RSTRING_PTR(orig), RSTRING_LEN(orig));
    rb_enc_cr_str_copy_for_substr(str, orig);
    OBJ_INFECT(str, orig);
    return str_succ(str);
}

next! → str Show source

相当于String#succ,但修改了接收器。

static VALUE
rb_str_succ_bang(VALUE str)
{
    rb_str_modify(str);
    str_succ(str);
    return str;
}

oct → integer Show source

str的前导字符视为八进制数字串(带有可选符号)并返回相应的数字。如果转换失败,则返回0。

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

如果str开始带有0,基数指标是荣幸的。看看Kernel#Integer。

static VALUE
rb_str_oct(VALUE str)
{
    return rb_str_to_inum(str, -8, FALSE);
}

ord → integer Show source

返回Integer单字符串的序数。

"a".ord         #=> 97
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);
}

partition(sep) → head, sep, tail()

partition(regexp) → head, match, tail

搜索字符串中的sep或pattern(regexp),并返回它之前的部分,匹配以及其后的部分。如果找不到,则返回两个空字符串和str

"hello".partition("l")         #=> ["he", "l", "lo"]
"hello".partition("x")         #=> ["hello", "", ""]
"hello".partition(/.l/)        #=> ["h", "el", "lo"]
static VALUE
rb_str_partition(VALUE str, VALUE sep)
{
    long pos;

    sep = get_pat_quoted(sep, 0);
    if (RB_TYPE_P(sep, T_REGEXP)) {
        pos = rb_reg_search(sep, str, 0, 0);
        if (pos < 0) {
          failed:
            return rb_ary_new3(3, str, str_new_empty(str), str_new_empty(str));
        }
        sep = rb_str_subpat(str, sep, INT2FIX(0));
        if (pos == 0 && RSTRING_LEN(sep) == 0) goto failed;
    }
    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)));
}

prepend(other_str1, other_str2,...) → str Show source

Prepend - 将给定的字符串添加到str

a = "!"
a.prepend("hello ", "world") #=> "hello world!"
a                            #=> "hello world!"

另见#concat。

static VALUE
rb_str_prepend_multi(int argc, VALUE *argv, VALUE str)
{
    str_modifiable(str);

    if (argc > 0) {
        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;
}

replace(other_str) → str Show source

使用other_str中的相应值替换str的内容和污点

s = "hello"         #=> "hello"
s.replace "world"   #=> "world"
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);
}

reverse → new_str Show source

以相反的顺序返回一个新字符串,其中的字符来自str

"stressed".reverse   #=> "desserts"
static VALUE
rb_str_reverse(VALUE str)
{
    rb_encoding *enc;
    VALUE rev;
    char *s, *e, *p;
    int cr;

    if (RSTRING_LEN(str) <= 1) return rb_str_dup(str);
    enc = STR_ENC_GET(str);
    rev = rb_str_new_with_class(str, 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));
    OBJ_INFECT_RAW(rev, str);
    str_enc_copy(rev, str);
    ENC_CODERANGE_SET(rev, cr);

    return rev;
}

reverse! → str Show source

反转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;
}

rindex(substring , integer) → integer or nil Show source

rindex(regexp , integer) → integer or nil

返回str中给定子字符串或模式(regexp)的最后一次出现的索引。如果找不到nil,则返回。如果第二个参数存在,它将指定字符串中结束搜索字符的位置。

"hello".rindex('e')             #=> 1
"hello".rindex('l')             #=> 3
"hello".rindex('a')             #=> nil
"hello".rindex(?e)              #=> 1
"hello".rindex(/[aeiou]/, -2)   #=> 1
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 (SPECIAL_CONST_P(sub)) goto generic;
    switch (BUILTIN_TYPE(sub)) {
      case T_REGEXP:
        /* enc = rb_get_check(str, sub); */
        pos = str_offset(RSTRING_PTR(str), RSTRING_END(str), pos,
                         enc, single_byte_optimizable(str));

        pos = rb_reg_search(sub, str, pos, 1);
        pos = rb_str_sublen(str, pos);
        if (pos >= 0) return LONG2NUM(pos);
        break;

      generic:
      default: {
        VALUE tmp;

        tmp = rb_check_string_type(sub);
        if (NIL_P(tmp)) {
            rb_raise(rb_eTypeError, "type mismatch: %s given",
                     rb_obj_classname(sub));
        }
        sub = tmp;
      }
        /* fall through */
      case T_STRING:
        pos = rb_str_rindex(str, sub, pos);
        if (pos >= 0) return LONG2NUM(pos);
        break;
    }
    return Qnil;
}

rjust(integer, padstr=' ') → new_str Show source

如果整数大于str的长度,则返回一个新String的长度整数,其中str右对齐并用padstr填充; 否则,返回str

"hello".rjust(4)            #=> "hello"
"hello".rjust(20)           #=> "               hello"
"hello".rjust(20, '1234')   #=> "123412341234123hello"
static VALUE
rb_str_rjust(int argc, VALUE *argv, VALUE str)
{
    return rb_str_justify(argc, argv, str, 'r');
}

rpartition(sep) → head, sep, tail()

rpartition(regexp) → head, match, tail

从字符串的末尾搜索字符串中的sep或pattern(regexp),并返回它之前的部分,匹配以及后面的部分。如果找不到,则返回两个空字符串和str

"hello".rpartition("l")         #=> ["hel", "l", "o"]
"hello".rpartition("x")         #=> ["", "", "hello"]
"hello".rpartition(/.l/)        #=> ["he", "ll", "o"]
static VALUE
rb_str_rpartition(VALUE str, VALUE sep)
{
    long pos = RSTRING_LEN(str);
    int regex = FALSE;

    if (RB_TYPE_P(sep, T_REGEXP)) {
        pos = rb_reg_search(sep, str, pos, 1);
        regex = TRUE;
    }
    else {
        VALUE tmp;

        tmp = rb_check_string_type(sep);
        if (NIL_P(tmp)) {
            rb_raise(rb_eTypeError, "type mismatch: %s given",
                     rb_obj_classname(sep));
        }
        sep = tmp;
        pos = rb_str_sublen(str, pos);
        pos = rb_str_rindex(str, sep, pos);
    }
    if (pos < 0) {
        return rb_ary_new3(3, str_new_empty(str), str_new_empty(str), str);
    }
    if (regex) {
        sep = rb_reg_nth_match(0, rb_backref_get());
    }
    else {
        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)));
}

rstrip → new_str Show source

返回删除了尾随空白的str的副本。另见String#lstripString#strip

请参阅strip空白的定义。

"  hello  ".rstrip   #=> "  hello"
"hello".rstrip       #=> "hello"
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 rb_str_dup(str);
    return rb_str_subseq(str, 0, olen-roffset);
}

rstrip! → self or nil Show source

删除str后面的空格,nil如果没有更改则返回。另见String#lstrip!String#strip!

请参阅strip空白的定义。

"  hello  ".rstrip!  #=> "  hello"
"  hello".rstrip!    #=> nil
"hello".rstrip!      #=> 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;
}

scan(pattern) → array Show source

scan(pattern) {|match, ...| block } → str

这两个表单迭代str,匹配模式(可能是a Regexp或a 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
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))) {
            last = prev;
            prev = start;
            rb_ary_push(ary, result);
        }
        if (last >= 0) rb_pat_search(pat, str, last, 1);
        return ary;
    }

    while (!NIL_P(result = scan_once(str, pat, &start))) {
        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;
}

scanf(fstr) { |current_match| ... } Show source

扫描当前字符串。如果给出了一个块,它的功能与block_scanf完全相同。

arr = "123 456".scanf("%d%d")
# => [123, 456]

require 'pp'

"this 123 read that 456 other".scanf("%s%d%s") {|m| pp m}

# ["this", 123, "read"]
# ["that", 456, "other"]
# => [["this", 123, "read"], ["that", 456, "other"]]

有关创建格式字符串的详细信息,请参阅Scanf。

你将需要'scanf'来使用#scanf

# File lib/scanf.rb, line 719
def scanf(fstr,&b) #:yield: current_match
  if b
    block_scanf(fstr,&b)
  else
    fs =
      if fstr.is_a? Scanf::FormatString
        fstr
      else
        Scanf::FormatString.new(fstr)
      end
    fs.match(self)
  end
end

scrub → new_str Show source

scrub(repl) → new_str

scrub{|bytes|} → new_str

如果字符串是无效的字节序列,则用给定的替换字符替换无效字节,否则返回自我。如果给出块,则用块的返回值替换无效字节。

"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>"
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) ? rb_str_dup(str): new;
}

scrub! → str Show source

scrub!(repl) → str

scrub!{|bytes|} → str

如果字符串是无效的字节序列,则用给定的替换字符替换无效字节,否则返回自我。如果给出块,则用块的返回值替换无效字节。

"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>"
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;
}

setbyte(index, integer) → integer Show source

修改index_th字节为_integer

static VALUE
rb_str_setbyte(VALUE str, VALUE index, VALUE value)
{
    long pos = NUM2LONG(index);
    int byte = NUM2INT(value);
    long len = RSTRING_LEN(str);
    char *head, *ptr, *left = 0;
    rb_encoding *enc;
    int cr = ENC_CODERANGE_UNKNOWN, width, nlen;

    if (pos < -len || len <= pos)
        rb_raise(rb_eIndexError, "index %ld out of string", pos);
    if (pos < 0)
        pos += len;

    if (!str_independent(str))
        str_make_independent(str);
    enc = STR_ENC_GET(str);
    head = RSTRING_PTR(str);
    ptr = &head[pos];
    if (!STR_EMBEDDABLE_P(len, rb_enc_mbminlen(enc))) {
        cr = ENC_CODERANGE(str);
        switch (cr) {
          case ENC_CODERANGE_7BIT:
            left = ptr;
            *ptr = byte;
            if (ISASCII(byte)) break;
            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;
}

shellescape → string Show source

转义str以便它可以安全地在Bourne shell命令行中使用。

有关详细信息,请参阅Shellwords#shellescape。

# File lib/shellwords.rb, line 214
def shellescape
  Shellwords.escape(self)
end

shellsplit → array Show source

str按照与UNIX Bourne shell相同的方式分割为一组令牌。

有关详细信息,请参阅Shellwords#shellsplit。

# File lib/shellwords.rb, line 203
def shellsplit
  Shellwords.split(self)
end

size → integer Show source

返回str的字符长度。

VALUE
rb_str_length(VALUE str)
{
    return LONG2NUM(str_strlen(str, NULL));
}

slice(index) → new_str or nil Show source

slice(start, length) → new_str or nil

slice(range) → new_str or nil

slice(regexp) → new_str or nil

slice(regexp, capture) → new_str or nil

slice(match_str) → new_str or nil

元素引用 - 如果传递单个元素index,则返回该索引处的一个字符的子字符串。如果传递一个start索引,并且length返回一个包含lengthstart索引开始的字符的子字符串。如果传递了a range,则它的开始和结束被解释为定义要返回的子字符串的偏移量。

在这三种情况下,如果索引是负数,则从字符串的末尾开始计数。对于startrange案件的起始索引仅仅是一个性格和匹配字符串的大小的指标之前。此外,如果字符范围的起始索引位于字符串的末尾,则会返回空字符串。

返回nil如果初始索引落在串外侧或长度为负。

如果Regexp被提供 ,则返回该字符串的匹配部分。如果capture遵循正则表达式(可能是捕获组索引或名称),则遵循正则表达式,而是返回MatchData的组件。

如果给出match_str,则返回该字符串,如果它出现在字符串中。

如果正则表达式不匹配或无法找到匹配字符串,则返回nil

a = "hello there"

a[1]                   #=> "e"
a[2, 3]                #=> "llo"
a[2..3]                #=> "ll"

a[-3, 2]               #=> "er"
a[7..-2]               #=> "her"
a[-4..-2]              #=> "her"
a[-2..-4]              #=> ""

a[11, 0]               #=> ""
a[11]                  #=> nil
a[12, 0]               #=> nil
a[12..-1]              #=> nil

a[/[aeiou](.)\1/]      #=> "ell"
a[/[aeiou](.)\1/, 0]   #=> "ell"
a[/[aeiou](.)\1/, 1]   #=> "l"
a[/[aeiou](.)\1/, 2]   #=> nil

a[/(?<vowel>[aeiou])(?<non_vowel>[^aeiou])/, "non_vowel"] #=> "l"
a[/(?<vowel>[aeiou])(?<non_vowel>[^aeiou])/, "vowel"]     #=> "e"

a["lo"]                #=> "lo"
a["bye"]               #=> 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]);
}

slice!(integer) → new_str or nil Show source

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

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"
static VALUE
rb_str_slice_bang(int argc, VALUE *argv, VALUE str)
{
    VALUE result;
    VALUE buf[3];
    int i;

    rb_check_arity(argc, 1, 2);
    for (i=0; i<argc; i++) {
        buf[i] = argv[i];
    }
    str_modify_keep_cr(str);
    result = rb_str_aref_m(argc, buf, str);
    if (!NIL_P(result)) {
        buf[i] = rb_str_new(0,0);
        rb_str_aset_m(argc+1, buf, str);
    }
    return result;
}

split(pattern=nil, limit) → anArray Show source

根据分隔符将str划分为子字符串,并返回这些子字符串的数组。

如果pattern是a String,则在分割str时将其内容用作分隔符。如果pattern是单个空格,则str将以空白符分割,前导空格和忽略连续空白字符的运行。

如果pattern是a Regexp,则str在模式匹配的地方被分割。只要模式匹配一​​个零长度的字符串,str就会被分割成单独的字符。如果模式包含组,则相应的匹配也会返回到数组中。

如果patternnil$;则使用该值。如果$;nil(这是默认值),则str被分割为空白,就像指定了''一样。

如果省略limit参数,则会禁止拖尾空字段。如果limit是一个正数,那么最多返回的字段数量(如果是limit1,整个字符串将作为数组中唯一的条目返回)。如果为负值,则返回的字段数没有限制,并且不会抑制尾随空字段。

当输入str为空时,返回空数组,因为该字符串被认为没有要分割的字段。

" 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", "", ""]

"".split(',', -1)               #=> []
static VALUE
rb_str_split_m(int argc, VALUE *argv, VALUE str)
{
    rb_encoding *enc;
    VALUE spat;
    VALUE limit;
    enum {awk, string, regexp} split_type;
    long beg, end, i = 0;
    int lim = 0;
    VALUE result, tmp;

    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 rb_ary_new2(0);
            return rb_ary_new3(1, str);
        }
        i = 1;
    }

    enc = STR_ENC_GET(str);
    split_type = regexp;
    if (!NIL_P(spat)) {
        spat = get_pat_quoted(spat, 0);
    }
    else if (NIL_P(spat = rb_fs)) {
        split_type = awk;
    }
    else if (!(spat = rb_fs_check(spat))) {
        rb_raise(rb_eTypeError, "value of $; must be String or Regexp");
    }
    if (split_type != awk) {
        if (BUILTIN_TYPE(spat) == T_STRING) {
            rb_encoding *enc2 = STR_ENC_GET(spat);

            mustnot_broken(spat);
            split_type = string;
            if (RSTRING_LEN(spat) == 0) {
                /* Special case - split into chars */
                spat = rb_reg_regcomp(spat);
                split_type = regexp;
            }
            else if (rb_enc_asciicompat(enc2) == 1) {
                if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') {
                    split_type = awk;
                }
            }
            else {
                int l;
                if (rb_enc_ascget(RSTRING_PTR(spat), RSTRING_END(spat), &l, enc2) == ' ' &&
                    RSTRING_LEN(spat) == l) {
                    split_type = awk;
                }
            }
        }
    }

    result = rb_ary_new();
    beg = 0;
    if (split_type == awk) {
        char *ptr = RSTRING_PTR(str);
        char *eptr = RSTRING_END(str);
        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)) {
                    rb_ary_push(result, rb_str_subseq(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)) {
                    rb_ary_push(result, rb_str_subseq(str, beg, end-beg));
                    skip = 1;
                    beg = ptr - bptr;
                    if (!NIL_P(limit)) ++i;
                }
                else {
                    end = ptr - bptr;
                }
            }
        }
    }
    else if (split_type == string) {
        char *ptr = RSTRING_PTR(str);
        char *temp = ptr;
        char *eptr = RSTRING_END(str);
        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;
            }
            rb_ary_push(result, rb_str_subseq(str, ptr - temp, end));
            ptr += end + slen;
            if (!NIL_P(limit) && lim <= ++i) break;
        }
        beg = ptr - temp;
    }
    else {
        char *ptr = RSTRING_PTR(str);
        long len = RSTRING_LEN(str);
        long start = beg;
        long idx;
        int last_null = 0;
        struct re_registers *regs;

        while ((end = rb_reg_search(spat, str, start, 0)) >= 0) {
            regs = RMATCH_REGS(rb_backref_get());
            if (start == end && BEG(0) == END(0)) {
                if (!ptr) {
                    rb_ary_push(result, str_new_empty(str));
                    break;
                }
                else if (last_null == 1) {
                    rb_ary_push(result, rb_str_subseq(str, beg,
                                                      rb_enc_fast_mbclen(ptr+beg,
                                                                         ptr+len,
                                                                         enc)));
                    beg = start;
                }
                else {
                    if (start == len)
                        start++;
                    else
                        start += rb_enc_fast_mbclen(ptr+start,ptr+len,enc);
                    last_null = 1;
                    continue;
                }
            }
            else {
                rb_ary_push(result, rb_str_subseq(str, beg, end-beg));
                beg = start = END(0);
            }
            last_null = 0;

            for (idx=1; idx < regs->num_regs; idx++) {
                if (BEG(idx) == -1) continue;
                if (BEG(idx) == END(idx))
                    tmp = str_new_empty(str);
                else
                    tmp = rb_str_subseq(str, BEG(idx), END(idx)-BEG(idx));
                rb_ary_push(result, tmp);
            }
            if (!NIL_P(limit) && lim <= ++i) break;
        }
    }
    if (RSTRING_LEN(str) > 0 && (!NIL_P(limit) || RSTRING_LEN(str) > beg || lim < 0)) {
        if (RSTRING_LEN(str) == beg)
            tmp = str_new_empty(str);
        else
            tmp = rb_str_subseq(str, beg, RSTRING_LEN(str)-beg);
        rb_ary_push(result, tmp);
    }
    if (NIL_P(limit) && lim == 0) {
        long len;
        while ((len = RARRAY_LEN(result)) > 0 &&
               (tmp = RARRAY_AREF(result, len-1), RSTRING_LEN(tmp) == 0))
            rb_ary_pop(result);
    }

    return result;
}

squeeze(other_str*) → new_str Show source

使用所描述的过程从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"
static VALUE
rb_str_squeeze(int argc, VALUE *argv, VALUE str)
{
    str = rb_str_dup(str);
    rb_str_squeeze_bang(argc, argv, str);
    return str;
}

squeeze!(other_str*) → str or nil Show source

挤压str,返回str,或者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;
    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 = RSTRING_PTR(str);
    if (!s || RSTRING_LEN(str) == 0) return Qnil;
    send = RSTRING_END(str);
    save = -1;
    ascompat = rb_enc_asciicompat(enc);

    if (singlebyte) {
        while (s < send) {
            unsigned int c = *(unsigned char*)s++;
            if (c != save || (argc > 0 && !squeez[c])) {
                *t++ = save = c;
            }
        }
    }
    else {
        while (s < send) {
            unsigned int c;
            int clen;

            if (ascompat && (c = *(unsigned char*)s) < 0x80) {
                if (c != save || (argc > 0 && !squeez[c])) {
                    *t++ = save = c;
                }
                s++;
            }
            else {
                c = rb_enc_codepoint_len(s, 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(t, TERM_LEN(str));
    if (t - RSTRING_PTR(str) != RSTRING_LEN(str)) {
        STR_SET_LEN(str, t - RSTRING_PTR(str));
        modify = 1;
    }

    if (modify) return str;
    return Qnil;
}

start_with?(prefixes+) → true or false Show source

如果strprefixes给定的一个开始,则返回true 。

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

# returns true if one of the prefixes matches.
"hello".start_with?("heaven", "hell")     #=> true
"hello".start_with?("heaven", "paradise") #=> 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];
        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;
}

strip → new_str Show source

返回删除了前导空白和尾随空白的str的副本。

空格被定义为以下任何字符:空,水平制表符,换行符,垂直制表符,换页符,回车符,空格。

"    hello    ".strip   #=> "hello"
"\tgoodbye\r\n".strip   #=> "goodbye"
"\x00\t\n\v\f\r ".strip #=> ""
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 rb_str_dup(str);
    return rb_str_subseq(str, loffset, olen-loffset-roffset);
}

strip! → str or nil Show source

str中删除前导和尾随空白。如果str未被更改,则返回nil

请参阅strip空白的定义。

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;
}

sub(pattern, replacement) → new_str Show source

sub(pattern, hash) → new_str

sub(pattern) {|match| block } → new_str

返回由第二个参数替换str第一个匹配项的副本pattern。这pattern通常是一个正则表达式; 如果以字符串的形式给出,它所包含的任何正则表达式元字符将按字面解释,例如,'\\d'将匹配反斜杠后跟'd',而不是数字。

如果replacement是一个字符串,它将被替换为匹配的文本。它可能包含对模式的表单捕获组的反引用"\d",其中d是组号,或者"\k<n>",其中n是组名。如果它是一个双引号字符串,则两个反引用前都必须加上一个额外的反斜杠。但是,在replacement特殊匹配变量中,例如$&,不会引用当前匹配。如果replacement是一个字符串,看起来像一个模式的捕获组,但实际上并不是一个模式捕获组,例如"\'",那么它必须在前面加上两个反斜杠,如下所示"\\'"

如果第二个参数是散列,并且匹配的文本是其中一个键,则相应的值是替换字符串。

在块形式中,当前匹配字符串传递作为参数,以及诸如变量$1$2$`$&,和$'将被适当地设定。该块返回的值将被替换为每次调用的匹配。

结果会继承原始字符串或任何提供的替换字符串中的任何污点。

"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?"
static VALUE
rb_str_sub(int argc, VALUE *argv, VALUE str)
{
    str = rb_str_dup(str);
    rb_str_sub_bang(argc, argv, str);
    return str;
}

sub!(pattern, replacement) → str or nil Show source

sub!(pattern) {|match| block } → str or nil

在原地执行与#sub相同的替换。

返回str是否执行了替换或未执行nil替换。

static VALUE
rb_str_sub_bang(int argc, VALUE *argv, VALUE str)
{
    VALUE pat, repl, hash = Qnil;
    int iter = 0;
    int tainted = 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);
        }
        tainted = OBJ_TAINTED_RAW(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);
        tainted |= OBJ_TAINTED_RAW(repl);
        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;
        rp = RSTRING_PTR(repl); 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);
        }
        memcpy(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);
        FL_SET_RAW(str, tainted);

        return str;
    }
    return Qnil;
}

succ → new_str Show source

返回str的后继者。后继者是通过从字符串中最右边的字母数字(或最右边的字符,如果没有字母数字)开始递增字符来计算的。增加一个数字总是会导致另一个数字,并且递增一个字母会导致另一个字母相同的情况。增加非字母数字使用底层字符集的整理顺序。

如果增量生成“进位”,则左侧的字符增加。这个过程重复,直到没有进位,如有必要添加一个额外的字符。

"abcd".succ        #=> "abce"
"THX1138".succ     #=> "THX1139"
"<<koala>>".succ   #=> "<<koalb>>"
"1999zzz".succ     #=> "2000aaa"
"ZZZ9999".succ     #=> "AAAA0000"
"***".succ         #=> "**+"
VALUE
rb_str_succ(VALUE orig)
{
    VALUE str;
    str = rb_str_new_with_class(orig, RSTRING_PTR(orig), RSTRING_LEN(orig));
    rb_enc_cr_str_copy_for_substr(str, orig);
    OBJ_INFECT(str, orig);
    return str_succ(str);
}

succ! → str Show source

相当于String#succ,但修改了接收器。

static VALUE
rb_str_succ_bang(VALUE str)
{
    rb_str_modify(str);
    str_succ(str);
    return str;
}

sum(n=16) → integer Show source

返回str中字符的基本n位校验和,其中n是可选参数,默认值为16.结果仅为str模中每个字节的二进制值的总和。这不是一个特别好的校验和。Integer2**n - 1

static VALUE
rb_str_sum(int argc, VALUE *argv, VALUE str)
{
    VALUE vbits;
    int bits;
    char *ptr, *p, *pend;
    long len;
    VALUE sum = INT2FIX(0);
    unsigned long sum0 = 0;

    if (argc == 0) {
        bits = 16;
    }
    else {
        rb_scan_args(argc, argv, "01", &vbits);
        bits = NUM2INT(vbits);
        if (bits < 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;
}

swapcase → new_str Show source

swapcase(options) → new_str

返回大写字母转换为小写字母和小写字符转换为大写字符的str的副本。

请参阅#downcase以了解其含义options并使用不同的编码。

"Hello".swapcase          #=> "hELLO"
"cYbEr_PuNk11".swapcase   #=> "CyBeR_pUnK11"
static VALUE
rb_str_swapcase(int argc, VALUE *argv, VALUE str)
{
    str = rb_str_dup(str);
    rb_str_swapcase_bang(argc, argv, str);
    return str;
}

swapcase! → str or nil Show source

swapcase!(options) → str or nil

相当于String#swapcase,但是修改了接收器,返回了str,或者nil没有更改。

请参阅#downcase以了解其含义options并使用不同的编码。

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_ENC_GET(str);
    rb_str_check_dummy_enc(enc);
    if (flags&ONIGENC_CASE_ASCII_ONLY)
        rb_str_ascii_casemap(str, &flags, enc);
    else
        str_shared_replace(str, rb_str_casemap(str, &flags, enc));

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

to_f → float Show source

返回str中作为浮点数解释前导字符的结果。超过有效数字末尾的无关字符将被忽略。如果str开始时没有有效的数字,0.0则返回。此方法从不引发异常。

"123.45e1".to_f        #=> 1234.5
"45.67 degrees".to_f   #=> 45.67
"thx1138".to_f         #=> 0.0
static VALUE
rb_str_to_f(VALUE str)
{
    return DBL2NUM(rb_str_to_dbl(str, FALSE));
}

to_i(base=10) → integer Show source

返回将str中的前导字符解释为整数基数(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
static VALUE
rb_str_to_i(int argc, VALUE *argv, VALUE str)
{
    int base;

    if (argc == 0) base = 10;
    else {
        VALUE b;

        rb_scan_args(argc, argv, "01", &b);
        base = NUM2INT(b);
    }
    if (base < 0) {
        rb_raise(rb_eArgError, "invalid radix %d", base);
    }
    return rb_str_to_inum(str, base, FALSE);
}

to_r → rational Show source

返回表示字符串形式的有理数。解析器忽略前导空白和尾随垃圾。任何数字序列都可以用下划线分隔。为null或垃圾字符串返回零。

注意:'0.3'.to_r与0.3.to_r不一样。前者相当于'3 / 10'to_r,但后者并非如此。

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

看Kernel.Rational。

static VALUE
string_to_r(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_rat(s, 0, &num);

    if (RB_FLOAT_TYPE_P(num))
        rb_raise(rb_eFloatDomainError, "Infinity");
    return num;
}

to_s → str Show source

to_str → str

Returns self.

如果在String的子类上调用,则将接收器转换为String对象。

static VALUE
rb_str_to_s(VALUE str)
{
    if (rb_obj_class(str) != rb_cString) {
        return str_duplicate(rb_cString, str);
    }
    return str;
}

to_str → str Show source

返回self

如果在String的子类上调用,则将接收器转换为String对象。

static VALUE
rb_str_to_s(VALUE str)
{
    if (rb_obj_class(str) != rb_cString) {
        return str_duplicate(rb_cString, str);
    }
    return str;
}

to_sym → symbol Show source

返回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"
VALUE
rb_str_intern(VALUE str)
{
#if USE_SYMBOL_GC
    rb_encoding *enc, *ascii;
    int type;
#else
    ID id;
#endif
    VALUE sym = lookup_str_sym(str);

    if (sym) {
	return sym;
    }

#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_new_frozen(str);
    }
    str = rb_fstring(str);
    type = rb_str_symname_type(str, IDSET_ATTRSET_FOR_INTERN);
    if (type < 0) type = ID_JUNK;
    return dsymbol_alloc(rb_cSymbol, str, enc, type);
#else
    id = intern_str(str, 0);
    return ID2SYM(id);
#endif
}

tr(from_str, to_str) → new_str Show source

返回str字符的副本,from_str替换为中的相应字符to_str。如果to_strfrom_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_strto_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'"
static VALUE
rb_str_tr(VALUE str, VALUE src, VALUE repl)
{
    str = rb_str_dup(str);
    tr_trans(str, src, repl, 0);
    return str;
}

tr!(from_str, to_str) → str or nil Show source

按照相同的规则翻译strString#tr。返回str,或者nil没有更改。

static VALUE
rb_str_tr_bang(VALUE str, VALUE src, VALUE repl)
{
    return tr_trans(str, src, repl, 0);
}

tr_s(from_str, to_str) → new_str Show source

如下所述处理str的副本String#tr,然后删除受翻译影响的区域中的重复字符。

"hello".tr_s('l', 'r')     #=> "hero"
"hello".tr_s('el', '*')    #=> "h*o"
"hello".tr_s('el', 'hx')   #=> "hhxo"
static VALUE
rb_str_tr_s(VALUE str, VALUE src, VALUE repl)
{
    str = rb_str_dup(str);
    tr_trans(str, src, repl, 1);
    return str;
}

tr_s!(from_str, to_str) → str or nil Show source

进行String#tr_s处理的海峡到位,返回海峡,或者nil如果未进行任何更改。

static VALUE
rb_str_tr_s_bang(VALUE str, VALUE src, VALUE repl)
{
    return tr_trans(str, src, repl, 1);
}

unicode_normalize(form=:nfc) Show source

Unicode标准化

str使用Unicode标准化NFC,NFD,NFKC或NFKD 返回标准化形式。所使用的规范化形式由form以下四个值中的任何一个确定:nfc,:nfd,:nfkc或:nfkd。默认是:nfc。

如果字符串不在Unicode编码中,则会引发异常。在这种情况下,“Unicode编码”是指任何UTF-8,UTF-16BE / LE和UTF-32BE / LE,以及GB18030,UCS_2BE和UCS_4BE。除了UTF-8以外的任何内容都是通过转换为UTF-8来实现的,这使得它比UTF-8更慢。

例子

"a\u0300".unicode_normalize        #=> 'à' (same as "\u00E0")
"a\u0300".unicode_normalize(:nfc)  #=> 'à' (same as "\u00E0")
"\u00E0".unicode_normalize(:nfd)   #=> 'à' (same as "a\u0300")
"\xE0".force_encoding('ISO-8859-1').unicode_normalize(:nfd)
                                   #=> Encoding::CompatibilityError raised
# File lib/unicode_normalize.rb, line 32
def unicode_normalize(form = :nfc)
  require 'unicode_normalize/normalize.rb' unless defined? UnicodeNormalize
  ## The following line can be uncommented to avoid repeated checking for
  ## UnicodeNormalize. However, tests didn't show any noticeable speedup
  ## when doing this. This comment also applies to the commented out lines
  ## in String#unicode_normalize! and String#unicode_normalized?.
  # String.send(:define_method, :unicode_normalize, ->(form = :nfc) { UnicodeNormalize.normalize(self, form) } )
  UnicodeNormalize.normalize(self, form)
end

unicode_normalize!(form=:nfc) Show source

#unicode_normalize的破坏性版本,正确执行Unicode规范化。

# File lib/unicode_normalize.rb, line 48
def unicode_normalize!(form = :nfc)
  require 'unicode_normalize/normalize.rb' unless defined? UnicodeNormalize
  # String.send(:define_method, :unicode_normalize!, ->(form = :nfc) { replace(unicode_normalize(form)) } )
  replace(unicode_normalize(form))
end

unicode_normalized?(form=:nfc) Show source

检查是否str使用Unicode规范化形式form,它是以下四个值中的任何一个:nfc,:nfd,:nfkc或:nfkd。默认是:nfc。

如果字符串不在Unicode编码中,则会引发异常。有关详细信息,请参阅#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
# File lib/unicode_normalize.rb, line 73
def unicode_normalized?(form = :nfc)
  require 'unicode_normalize/normalize.rb' unless defined? UnicodeNormalize
  # String.send(:define_method, :unicode_normalized?, ->(form = :nfc) { UnicodeNormalize.normalized?(self, form) } )
  UnicodeNormalize.normalized?(self, form)
end

unpack(format) → anArray Show source

根据格式字符串解码str(可能包含二进制数据),返回提取的每个值的数组。格式字符串由一系列单字符指令组成,总结在本条目结尾的表格中。每个指令后面可以跟一个数字,表示用该指令重复的次数。星号(“ *'')将用完所有剩余的元素。sSiIlL每个指令后面可以跟一个下划线(“ _'')或感叹号(” !''),以便将指定类型的底层平台的本地大小; 否则,它使用与平台无关的一致大小。格式字符串中的空格被忽略。另见String#unpack1Array#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开始提供。
static VALUE
pack_unpack(VALUE str, VALUE fmt)
{
    int mode = rb_block_given_p() ? UNPACK_BLOCK : UNPACK_ARRAY;
    return pack_unpack_internal(str, fmt, mode);
}

unpack1(format) → obj Show source

根据格式字符串解码str(可能包含二进制数据),返回提取的第一个值。另见String#unpackArray#pack

static VALUE
pack_unpack1(VALUE str, VALUE fmt)
{
    return pack_unpack_internal(str, fmt, UNPACK_1);
}

upcase → new_str Show source

upcase(options) → new_str

返回所有小写​​字母替换为大写字母的str的副本。

请参阅#downcase以了解其含义options并使用不同的编码。

"hEllO".upcase   #=> "HELLO"
static VALUE
rb_str_upcase(int argc, VALUE *argv, VALUE str)
{
    str = rb_str_dup(str);
    rb_str_upcase_bang(argc, argv, str);
    return str;
}

upcase! → str or nil Show source

upcase!(options) → str or nil

提升str的内容,nil如果没有更改则返回。

请参阅#downcase以了解其含义options并使用不同的编码。

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_ENC_GET(str);
    rb_str_check_dummy_enc(enc);
    if ((flags&ONIGENC_CASE_ASCII_ONLY) && (enc==rb_utf8_encoding() || rb_enc_mbmaxlen(enc)==1)
        || (!(flags&ONIGENC_CASE_FOLD_TURKISH_AZERI) && ENC_CODERANGE(str)==ENC_CODERANGE_7BIT)) {
        char *s = RSTRING_PTR(str), *send = RSTRING_END(str);

        while (s < send) {
            unsigned int c = *(unsigned char*)s;

            if (rb_enc_isascii(c, enc) && 'a' <= c && c <= 'z') {
                *s = 'A' + (c - 'a');
                flags |= ONIGENC_CASE_MODIFIED;
            }
            s++;
        }
    }
    else if (flags&ONIGENC_CASE_ASCII_ONLY)
        rb_str_ascii_casemap(str, &flags, enc);
    else
        str_shared_replace(str, rb_str_casemap(str, &flags, enc));

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

upto(other_str, exclusive=false) {|s| block } → str Show source

upto(other_str, exclusive=false) → an_enumerator

迭代通过连续的值,从str开始到end_str结束,将每个值依次传递给块。该String#succ方法用于生成每个值。如果省略可选的第二个参数exclusive或false,则会包含最后一个值; 否则会被排除。

如果没有给出块,则返回一个枚举器。

"a8".upto("b6") {|s| print s, ' ' }
for s in "a8".."b6"
  print s, ' '
end

生产:

a8 a9 b0 b1 b2 b3 b4 b5 b6
a8 a9 b0 b1 b2 b3 b4 b5 b6

如果strother_str仅包含ASCII数字字符,则它们都被识别为十进制数字。另外,字符串的宽度(例如前导零)被适当地处理。

"9".upto("11").to_a   #=> ["9", "10", "11"]
"25".upto("5").to_a   #=> []
"07".upto("11").to_a  #=> ["07", "08", "09", "10", "11"]
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 str_upto_each(beg, end, RTEST(exclusive), str_upto_i, Qnil);
}

valid_encoding? → true or false Show source

对于正确编码的字符串返回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
static VALUE
rb_str_valid_encoding_p(VALUE str)
{
    int cr = rb_enc_str_coderange(str);

    return cr == ENC_CODERANGE_BROKEN ? Qfalse : Qtrue;
}

字符串 | String相关

Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct