-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add chopprefix, chopsuffix #40995
add chopprefix, chopsuffix #40995
Conversation
Maybe |
base/strings/util.jl
Outdated
""" | ||
function chopprefix(s::AbstractString, prefix::AbstractString) | ||
if startswith(s, prefix) | ||
SubString(s, nextind(s, lastindex(prefix), 1), lastindex(s)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may not be correct if s
and prefix
are different subtypes of AbstractString
, since in that case lastindex(prefix)
may not be a correct index into s
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably we need two methods: one for AbstractString
arguments, and an optimized method for Union{String,SubString{String}}
arguments. (In the latter case you can just use 1+ncodeunits(prefix)
as the starting index.)
base/strings/util.jl
Outdated
if isempty(s) || !endswith(s, suffix) | ||
SubString(s) | ||
else | ||
SubString(s, firstindex(s), prevind(s, lastindex(s), length(suffix))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine in principle, but is a little suboptimal because length(suffix)
and prevind
require two extra O(length(suffix)
) loops. In the case where both s
and suffix
are of type String
or SubString{String}
, one option is to use thisind(s, ncodeunits(s) - ncodeunits(suffix))
.
(As above, we probably want two methods here, one optimized for String
.)
+1 for chophead, choptail |
Yes, I like chophead/choptail. Thanks @stevengj for the feedback, I'll add those optimisations shortly. |
It might be nice to avoid introducing a new function name entirely and instead just add this as a new method for
I always have trouble remembering which of these applies to any given situation. It would be nice if this could be added without adding more similarly sounding function names for slightly different versions of "get rid of something at the ends of a string". E.g., could adding this to |
The names chop(str, head="prefix")
chop(str, tail="suffix") Although those suggest to me that they might error if The trouble with defining julia> rstrip("Hello", collect("lo"))
"He" I actually expected Overall my favorite so far is |
Stylistically, I think I much prefer |
base/strings/util.jl
Outdated
if startswith(s, prefix) | ||
SubString(s, nextind(s, lastindex(prefix), 1), lastindex(s)) | ||
else | ||
SubString(s) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can do this fairly compactly as follows (startswith
could also be written this way, to show they are the same):
if startswith(s, prefix) | |
SubString(s, nextind(s, lastindex(prefix), 1), lastindex(s)) | |
else | |
SubString(s) | |
end | |
i, j = iterate(a), iterate(b) | |
while true | |
j === nothing && i === nothing && return SubString(s, 1, 0) # s == prefix: empty result | |
j === nothing && return SubString(s, i[2]) # ran out of prefix: success! | |
i === nothing && return SubString(s) # ran out of source: failure | |
i[1] == j[1] || return SubString(s) # mismatch: failure | |
i, j = iterate(a, i[2]), iterate(b, j[2]) | |
end |
Then the general chopend
is pretty much the same, but with slight changes (such as calling iterate(Iterators.Reverse(a))
at the top, and SubString(s, firstindex(s), i[2])
on success)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to just go ahead and take this over and finish it. I think it is ready to merge, but can add to triage if (@StefanKarpinski) we want to discuss merging chop|chopprefix|chopsuffix
into chop(s; [head], [tail] [prefix], [suffix])
and deciding which order to apply those in.
Thanks @vtjnash! |
LGTM, modulo bikeshedding the names. |
Lets bikeshed the names. |
Triage says 👍 |
Was this PR missing a NEWS? |
Co-authored-by: Jameson Nash <[email protected]>
Co-authored-by: Jameson Nash <[email protected]>
Attempt to address #38477