In Python, I can splice string like this:
solo = A quick brown fox jump over the lazy dog
solo[3:5]
I know substr
and comb
is enough, I want to know if it's possible, However. Should I use a role to do this?
How to slice a string
Strings (represented as class Str
) are seen as single values and not positional data structures in Perl 6, and thus can't be indexed/sliced with the built-in [ ]
array indexing operator.
As you already suggested, comb
or substr
is the way to go:
my $solo = "A quick brown fox jumps over the lazy dog";
dd $solo.comb[3..4].join; # "ui"
dd $solo.comb[3..^5].join; # "ui"
dd $solo.substr(3, 2); # "ui"
dd $solo.substr(3..4); # "ui"
dd $solo.substr(3..^5); # "ui"
If you want to modify the slice, use substr-rw
:
$solo.substr-rw(2..6) = "slow";
dd $solo; # "A slow brown fox jumps over the lazy dog"
How to make operator [ ]
work directly on strings
If you really wanted to, you could compose a role into your string that adds method AT-POS
, which would make the [ ]
operator work on it:
my $solo = "A quick brown fox jumps over the lazy dog" but role {
method AT-POS ($i) { self.substr($i, 1) }
}
dd $solo[3..5]; ("u", "i", "c")
However, this returns slices as a list, because that's what the [ ]
operator does by default. To make it return a concatenated string, you'd have to re-implement [ ]
for type Str
:
multi postcircumfix:<[ ]>(Str $string, Int:D $index) {
$string.substr($index, 1)
}
multi postcircumfix:<[ ]>(Str $string, Range:D $slice) {
$string.substr($slice)
}
multi postcircumfix:<[ ]>(Str $string, Iterable:D \slice) {
slice.map({ $string.substr($_, 1) }).join
}
my $solo = "A quick brown fox jumps over the lazy dog";
dd $solo[3]; # "u"
dd $solo[3..4]; # "ui"
dd $solo[3, 5]; # "uc"
You could extend the [ ]
multi-candidates added here to handle all the other magic that the operator provides for lists, like:
- from-the-end indices, e.g.
$solo[*-1]
- truncating slices, e.g.
$solo[3..*]
- adverbs, e.g.
$solo[3..5]:kv
- assignment, e.g.
$solo[2..6] = "slow"
But it would take a lot of effort to get all of that right.
Also, keep in mind that overriding built-in operators to do things they weren't supposed to do, will confuse other Perl 6 programmers who will have to review or work with your code in the future.
来源:https://stackoverflow.com/questions/41689023/how-can-i-slice-a-string-like-python-does-in-perl-6