diff options
| author | Burdette Lamar <BurdetteLamar@Yahoo.com> | 2025-10-10 15:39:05 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-10 16:39:05 -0400 |
| commit | 0090311db21b4c0e67a00a381156d7a8a1f6a262 (patch) | |
| tree | 2917c520ca6b2cc9a1342b3f710c0b10749eb163 | |
| parent | 0a6cd03b3d91f52c47242d2b45f5ac086a3c1fd8 (diff) | |
[DOC] String slices doc (#14740)
| -rw-r--r-- | doc/string.rb | 140 | ||||
| -rw-r--r-- | doc/string/aref.rdoc | 98 | ||||
| -rw-r--r-- | doc/string/aset.rdoc | 183 | ||||
| -rw-r--r-- | string.c | 50 |
4 files changed, 298 insertions, 173 deletions
diff --git a/doc/string.rb b/doc/string.rb index a5d143cf36..3f3461573f 100644 --- a/doc/string.rb +++ b/doc/string.rb @@ -159,146 +159,6 @@ # - #rstrip, #rstrip!: Strip trailing whitespace. # - #strip, #strip!: Strip leading and trailing whitespace. # -# == +String+ Slices -# -# A _slice_ of a string is a substring selected by certain criteria. -# -# These instance methods utilize slicing: -# -# - String#[] (aliased as String#slice): Returns a slice copied from +self+. -# - String#[]=: Mutates +self+ with the slice replaced. -# - String#slice!: Mutates +self+ with the slice removed and returns the removed slice. -# -# Each of the above methods takes arguments that determine the slice -# to be copied or replaced. -# -# The arguments have several forms. -# For a string +string+, the forms are: -# -# - <tt>string[index]</tt> -# - <tt>string[start, length]</tt> -# - <tt>string[range]</tt> -# - <tt>string[regexp, capture = 0]</tt> -# - <tt>string[substring]</tt> -# -# <b><tt>string[index]</tt></b> -# -# When a non-negative integer argument +index+ is given, -# the slice is the 1-character substring found in +self+ at character offset +index+: -# -# 'bar'[0] # => "b" -# 'bar'[2] # => "r" -# 'bar'[20] # => nil -# 'тест'[2] # => "с" -# 'こんにちは'[4] # => "は" -# -# When a negative integer +index+ is given, -# the slice begins at the offset given by counting backward from the end of +self+: -# -# 'bar'[-3] # => "b" -# 'bar'[-1] # => "r" -# 'bar'[-20] # => nil -# -# <b><tt>string[start, length]</tt></b> -# -# When non-negative integer arguments +start+ and +length+ are given, -# the slice begins at character offset +start+, if it exists, -# and continues for +length+ characters, if available: -# -# 'foo'[0, 2] # => "fo" -# 'тест'[1, 2] # => "ес" -# 'こんにちは'[2, 2] # => "にち" -# # Zero length. -# 'foo'[2, 0] # => "" -# # Length not entirely available. -# 'foo'[1, 200] # => "oo" -# # Start out of range. -# 'foo'[4, 2] # => nil -# -# Special case: if +start+ equals the length of +self+, -# the slice is a new empty string: -# -# 'foo'[3, 2] # => "" -# 'foo'[3, 200] # => "" -# -# When a negative +start+ and non-negative +length+ are given, -# the slice begins by counting backward from the end of +self+, -# and continues for +length+ characters, if available: -# -# 'foo'[-2, 2] # => "oo" -# 'foo'[-2, 200] # => "oo" -# # Start out of range. -# 'foo'[-4, 2] # => nil -# -# When a negative +length+ is given, there is no slice: -# -# 'foo'[1, -1] # => nil -# 'foo'[-2, -1] # => nil -# -# <b><tt>string[range]</tt></b> -# -# When a Range argument +range+ is given, -# it creates a substring of +string+ using the indices in +range+. -# The slice is then determined as above: -# -# 'foo'[0..1] # => "fo" -# 'foo'[0, 2] # => "fo" -# -# 'foo'[2...2] # => "" -# 'foo'[2, 0] # => "" -# -# 'foo'[1..200] # => "oo" -# 'foo'[1, 200] # => "oo" -# -# 'foo'[4..5] # => nil -# 'foo'[4, 2] # => nil -# -# 'foo'[-4..-3] # => nil -# 'foo'[-4, 2] # => nil -# -# 'foo'[3..4] # => "" -# 'foo'[3, 2] # => "" -# -# 'foo'[-2..-1] # => "oo" -# 'foo'[-2, 2] # => "oo" -# -# 'foo'[-2..197] # => "oo" -# 'foo'[-2, 200] # => "oo" -# -# <b><tt>string[regexp, capture = 0]</tt></b> -# -# When the Regexp argument +regexp+ is given, -# and the +capture+ argument is <tt>0</tt>, -# the slice is the first matching substring found in +self+: -# -# 'foo'[/o/] # => "o" -# 'foo'[/x/] # => nil -# s = 'hello there' -# s[/[aeiou](.)\1/] # => "ell" -# s[/[aeiou](.)\1/, 0] # => "ell" -# -# If the argument +capture+ is provided and not <tt>0</tt>, -# it should be either a capture group index (integer) -# or a capture group name (String or Symbol); -# the slice is the specified capture -# (see {Groups and Captures}[rdoc-ref:Regexp@Groups+and+Captures]): -# -# s = 'hello there' -# s[/[aeiou](.)\1/, 1] # => "l" -# s[/(?<vowel>[aeiou])(?<non_vowel>[^aeiou])/, "non_vowel"] # => "l" -# s[/(?<vowel>[aeiou])(?<non_vowel>[^aeiou])/, :vowel] # => "e" -# -# If an invalid capture group index is given, there is no slice. -# If an invalid capture group name is given, +IndexError+ is raised. -# -# <b><tt>string[substring]</tt></b> -# -# When the single +String+ argument +substring+ is given, -# it returns the substring from +self+ if found, otherwise +nil+: -# -# 'foo'['oo'] # => "oo" -# 'foo'['xx'] # => nil -# # == What's Here # # First, what's elsewhere. Class +String+: diff --git a/doc/string/aref.rdoc b/doc/string/aref.rdoc new file mode 100644 index 0000000000..bd33c4c050 --- /dev/null +++ b/doc/string/aref.rdoc @@ -0,0 +1,98 @@ +Returns the substring of +self+ specified by the arguments. + +<b>Form <tt>self[index]</tt></b> + +With non-negative integer argument +index+ given, +returns the 1-character substring found in self at character offset index: + + 'hello'[0] # => "h" + 'hello'[4] # => "o" + 'hello'[5] # => nil + 'тест'[2] # => "с" + 'こんにちは'[4] # => "は" + +With negative integer argument +index+ given, +counts backward from the end of +self+: + + 'hello'[-1] # => "o" + 'hello'[-5] # => "h" + 'hello'[-6] # => nil + +<b>Form <tt>self[start, length]</tt></b> + +With integer arguments +start+ and +length+ given, +returns a substring of size +length+ characters (as available) +beginning at character offset specified by +start+. + +If argument +start+ is non-negative, +the offset is +start+: + + 'hello'[0, 1] # => "h" + 'hello'[0, 5] # => "hello" + 'hello'[0, 6] # => "hello" + 'hello'[2, 3] # => "llo" + 'hello'[2, 0] # => "" + 'hello'[2, -1] # => nil + +If argument +start+ is negative, +counts backward from the end of +self+: + + 'hello'[-1, 1] # => "o" + 'hello'[-5, 5] # => "hello" + 'hello'[-1, 0] # => "" + 'hello'[-6, 5] # => nil + +Special case: if +start+ equals the length of +self+, +returns a new empty string: + + 'hello'[5, 3] # => "" + +<b>Form <tt>self[range]</tt></b> + +With Range argument +range+ given, +forms substring <tt>self[range.start, range.size]</tt>: + + 'hello'[0..2] # => "hel" + 'hello'[0, 3] # => "hel" + + 'hello'[0...2] # => "he" + 'hello'[0, 2] # => "he" + + 'hello'[0, 0] # => "" + 'hello'[0...0] # => "" + +<b>Form <tt>self[regexp, capture = 0]</tt></b> + +With Regexp argument +regexp+ given and +capture+ as zero, +searches for a matching substring in +self+; +updates {Regexp-related global variables}[rdoc-ref:Regexp@Global+Variables]: + + 'hello'[/ell/] # => "ell" + 'hello'[/l+/] # => "ll" + 'hello'[//] # => "" + 'hello'[/nosuch/] # => nil + +With +capture+ as a positive integer +n+, +returns the +n+th matched group: + + 'hello'[/(h)(e)(l+)(o)/] # => "hello" + 'hello'[/(h)(e)(l+)(o)/, 1] # => "h" + $1 # => "h" + 'hello'[/(h)(e)(l+)(o)/, 2] # => "e" + $2 # => "e" + 'hello'[/(h)(e)(l+)(o)/, 3] # => "ll" + 'hello'[/(h)(e)(l+)(o)/, 4] # => "o" + 'hello'[/(h)(e)(l+)(o)/, 5] # => nil + +<b>Form <tt>self[substring]</tt></b> + +With string argument +substring+ given, +returns the matching substring of +self+, if found: + + 'hello'['ell'] # => "ell" + 'hello'[''] # => "" + 'hello'['nosuch'] # => nil + 'тест'['ес'] # => "ес" + 'こんにちは'['んにち'] # => "んにち" + +Related: see {Converting to New String}[rdoc-ref:String@Converting+to+New+String]. diff --git a/doc/string/aset.rdoc b/doc/string/aset.rdoc new file mode 100644 index 0000000000..e06680d16c --- /dev/null +++ b/doc/string/aset.rdoc @@ -0,0 +1,183 @@ +Returns +self+ with all, a substring, or none of its contents replaced; +returns the argument +other_string+. + +<b>Form <tt>self[index] = other_string</tt></b> + +With non-negative integer argument +index+ given, +searches for the 1-character substring found in self at character offset index: + + s = 'hello' + s[0] = 'foo' # => "foo" + s # => "fooello" + + s = 'hello' + s[4] = 'foo' # => "foo" + s # => "hellfoo" + + s = 'hello' + s[5] = 'foo' # => "foo" + s # => "hellofoo" + + s = 'hello' + s[6] = 'foo' # Raises IndexError: index 6 out of string. + +With negative integer argument +index+ given, +counts backward from the end of +self+: + + s = 'hello' + s[-1] = 'foo' # => "foo" + s # => "hellfoo" + + s = 'hello' + s[-5] = 'foo' # => "foo" + s # => "fooello" + + s = 'hello' + s[-6] = 'foo' # Raises IndexError: index -6 out of string. + +<b>Form <tt>self[start, length] = other_string</tt></b> + +With integer arguments +start+ and +length+ given, +searches for a substring of size +length+ characters (as available) +beginning at character offset specified by +start+. + +If argument +start+ is non-negative, +the offset is +start': + + s = 'hello' + s[0, 1] = 'foo' # => "foo" + s # => "fooello" + + s = 'hello' + s[0, 5] = 'foo' # => "foo" + s # => "foo" + + s = 'hello' + s[0, 9] = 'foo' # => "foo" + s # => "foo" + + s = 'hello' + s[2, 0] = 'foo' # => "foo" + s # => "hefoollo" + + s = 'hello' + s[2, -1] = 'foo' # Raises IndexError: negative length -1. + +If argument +start+ is negative, +counts backward from the end of +self+: + + s = 'hello' + s[-1, 1] = 'foo' # => "foo" + s # => "hellfoo" + + s = 'hello' + s[-1, 9] = 'foo' # => "foo" + s # => "hellfoo" + + s = 'hello' + s[-5, 2] = 'foo' # => "foo" + s # => "foollo" + + s = 'hello' + s[-3, 0] = 'foo' # => "foo" + s # => "hefoollo" + + s = 'hello' + s[-6, 2] = 'foo' # Raises IndexError: index -6 out of string. + +Special case: if +start+ equals the length of +self+, +the argument is appended to +self+: + + s = 'hello' + s[5, 3] = 'foo' # => "foo" + s # => "hellofoo" + +<b>Form <tt>self[range] = other_string</tt></b> + +With Range argument +range+ given, +equivalent to <tt>self[range.start, range.size] = other_string</tt>: + + s0 = 'hello' + s1 = 'hello' + s0[0..2] = 'foo' # => "foo" + s1[0, 3] = 'foo' # => "foo" + s0 # => "foolo" + s1 # => "foolo" + + s = 'hello' + s[0...2] = 'foo' # => "foo" + s # => "foollo" + + s = 'hello' + s[0...0] = 'foo' # => "foo" + s # => "foohello" + + s = 'hello' + s[9..10] = 'foo' # Raises RangeError: 9..10 out of range + +<b>Form <tt>self[regexp, capture = 0] = other_string</tt></b> + +With Regexp argument +regexp+ given and +capture+ as zero, +searches for a matching substring in +self+; +updates {Regexp-related global variables}[rdoc-ref:Regexp@Global+Variables]: + + s = 'hello' + s[/l/] = 'L' # => "L" + [$`, $&, $'] # => ["he", "l", "lo"] + s[/eLlo/] = 'owdy' # => "owdy" + [$`, $&, $'] # => ["h", "eLlo", ""] + s[/eLlo/] = 'owdy' # Raises IndexError: regexp not matched. + [$`, $&, $'] # => [nil, nil, nil] + +With +capture+ as a positive integer +n+, +searches for the +n+th matched group: + + s = 'hello' + s[/(h)(e)(l+)(o)/] = 'foo' # => "foo" + [$`, $&, $'] # => ["", "hello", ""] + + s = 'hello' + s[/(h)(e)(l+)(o)/, 1] = 'foo' # => "foo" + s # => "fooello" + [$`, $&, $'] # => ["", "hello", ""] + + s = 'hello' + s[/(h)(e)(l+)(o)/, 2] = 'foo' # => "foo" + s # => "hfoollo" + [$`, $&, $'] # => ["", "hello", ""] + + s = 'hello' + s[/(h)(e)(l+)(o)/, 4] = 'foo' # => "foo" + s # => "hellfoo" + [$`, $&, $'] # => ["", "hello", ""] + + s = 'hello' + # => "hello" + s[/(h)(e)(l+)(o)/, 5] = 'foo # Raises IndexError: index 5 out of regexp. + + s = 'hello' + s[/nosuch/] = 'foo' # Raises IndexError: regexp not matched. + +<b>Form <tt>self[substring] = other_string</tt></b> + +With string argument +substring+ given: + + s = 'hello' + s['l'] = 'foo' # => "foo" + s # => "hefoolo" + + s = 'hello' + s['ll'] = 'foo' # => "foo" + s # => "hefooo" + + s = 'тест' + s['ес'] = 'foo' # => "foo" + s # => "тfooт" + + s = 'こんにちは' + s['んにち'] = 'foo' # => "foo" + s # => "こfooは" + + s['nosuch'] = 'foo' # Raises IndexError: string not matched. + +Related: see {Modifying}[rdoc-ref:String@Modifying]. @@ -5809,10 +5809,8 @@ rb_str_aref(VALUE str, VALUE indx) * self[regexp, capture = 0] -> new_string or nil * self[substring] -> new_string or nil * - * Returns the substring of +self+ specified by the arguments. - * See examples at {String Slices}[rdoc-ref:String@String+Slices]. + * :include: doc/string/aref.rdoc * - * Related: see {Converting to New String}[rdoc-ref:String@Converting+to+New+String]. */ static VALUE @@ -6026,30 +6024,14 @@ rb_str_aset(VALUE str, VALUE indx, VALUE val) /* * call-seq: - * self[index] = new_string - * self[start, length] = new_string - * self[range] = new_string - * self[regexp, capture = 0] = new_string - * self[substring] = new_string - * - * Replaces all, some, or none of the contents of +self+; returns +new_string+. - * See {String Slices}[rdoc-ref:String@String+Slices]. + * self[index] = other_string -> new_string + * self[start, length] = other_string -> new_string + * self[range] = other_string -> new_string + * self[regexp, capture = 0] = other_string -> new_string + * self[substring] = other_string -> new_string * - * A few examples: - * - * s = 'foo' - * s[2] = 'rtune' # => "rtune" - * s # => "fortune" - * s[1, 5] = 'init' # => "init" - * s # => "finite" - * s[3..4] = 'al' # => "al" - * s # => "finale" - * s[/e$/] = 'ly' # => "ly" - * s # => "finally" - * s['lly'] = 'ncial' # => "ncial" - * s # => "financial" + * :include: doc/string/aset.rdoc * - * Related: see {Modifying}[rdoc-ref:String@Modifying]. */ static VALUE @@ -6100,18 +6082,20 @@ rb_str_insert(VALUE str, VALUE idx, VALUE str2) * slice!(regexp, capture = 0) -> new_string or nil * slice!(substring) -> new_string or nil * - * Removes and returns the substring of +self+ specified by the arguments. - * See {String Slices}[rdoc-ref:String@String+Slices]. + * Like String#[] (and its alias String#slice), except that: + * + * - Performs substitutions in +self+ (not in a copy of +self+). + * - Returns the removed substring if any modifications were made, +nil+ otherwise. * * A few examples: * - * 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" + * s = 'hello' + * s.slice!('e') # => "e" + * s # => "hllo" + * s.slice!('e') # => nil + * s # => "hllo" * + * Related: see {Modifying}[rdoc-ref:String@Modifying]. */ static VALUE |
