String Slice
Synopsis
Retrieve a slice of a string.
Syntax
Exp₁ [ Exp₂ .. Exp₄]Exp₁ [ Exp₂ , Exp3 .. Exp₄]
where Exp₂ and Exp₄ are optional.
Types
Exp₁ | Exp₂ | Exp₃ | Exp₄ | Exp₁ [ Exp₂ .. Exp₄ ] or Exp₁ [ Exp₂ , Exp₃ .. Exp₄] |
|---|---|---|---|---|
str | int | int | int | str |
Description
A String slice is similar to a list Slice and uses the integer values of Exp₂ and Exp₄ to determine the begin (inclusive) and end (exclusive)
of a slice from the string value S of Exp₁. Negative indices count from the end of the string backwards.
Using the second form, an extra index Exp₃ is given that determines the
index of the second element in the slice and establishes the step between
successive elements in the slice. The default step is 1.
If end is smaller than begin, the slice is constructed backwards.
Let Len be the length of S and let N₂, N₃ and N₄ be the respective values of the expressions
Exp₂, Exp₂ and Exp₂ when they are present.
The slice parameters begin, end, and step are determined as follows:
- Exp₂:
If Exp₂ is absent, then
begin = 0. Otherwise, if N₂ >= 0 thenbegin = N₂elsebegin = N₂ + Len. - Exp₄:
If Exp₄ is absent, then
end = Len. Otherwise, if N₄ >= 0, thenend = N₄elseend = N₄ + Len. - Exp₃:
If Exp₃ is absent, then if
begin < endthenstep = 1elsestep = -1. Otherwise, ifbegin < end, thenstep = N₃ - beginelsestep = begin - N₃.
Now, the constraints 0 <= begin < Len and 0 < end < Len should hold,
otherwise the exception IndexOutOfBounds is thrown.
The slice consists of the elements S[begin], S[begin+step], S[end - step].
When begin >= end, the elements are listed in reverse order.
Examples
Consider the string S = "abcdefghi"; (with size 9) as running example.
Here is a view on L that will help to correlate positive and negative indices:
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|---|
S[i] | "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
-i | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 |
Some common use cases (with begin <= end):
| Slice | Means: |
|---|---|
S[begin..end] | characters with indices begin through end-1 |
S[begin..] | characters with indices begin through the rest of the string |
S[..end] | characters with indices from the beginning through end-1 |
S[..] | the whole list |
S[-1] | last element of the string |
S[-2..] | the last two characters of the string |
S[..-2] | all characters except the last two. |
Let's put this into practice now.
rascal>S = "abcdefghi";
str: "abcdefghi"
───
abcdefghi
───
Slices with begin < end
rascal>S[1..3];
str: "bc"
───
bc
───
rascal>S[1..]; // empty end => end of string
str: "bcdefghi"
───
bcdefghi
───
rascal>S[..3]; // empty begin => first character of string
str: "abc"
───
abc
───
rascal>S[..]; // both empty => whole string
str: "abcdefghi"
───
abcdefghi
───
Slices with begin >= end
rascal>S[3..1]; // slice contains characters with indices 3 and 2 (in that order)
str: "dc"
───
dc
───
rascal>S[3..3]; // empty slice when begin == end
str: ""
───
───
Slices with negative begin or end:
rascal>S[2..-2]; // equivalent to S[2..7]
str: "cdefg"
───
cdefg
───
rascal>S[2..7];
str: "cdefg"
───
cdefg
───
rascal>S[-4..-2]; // equivalent to S[5..7]
str: "fg"
───
fg
───
rascal>S[5..7];
str: "fg"
───
fg
───
Slices with an explicit second index:
rascal>S[1,3..6];
str: "bdf"
───
bdf
───
rascal>S[5,3..];
str: "fdb"
───
fdb
───
Slicing does not go "out of bounds"; it just stops at the end if you go beyond the end or the beginning:
rascal>S[..10];
str: "abcdefghi"
───
abcdefghi
───
rascal>S[..-11];
str: "a"
───
a
───