Project

General

Profile

Feature #12694

Want a String method to remove heading substr

Added by sonots (Naotoshi Seo) over 1 year ago. Updated 5 months ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:77016]

Description

I often write codes like:

str = 'abcdef'
substr = 'abc'
str[substr.size..-1] if str.start_with?(substr) #=> 'def'
# or
str.sub(/\A#{Regexp.escape(substr)}/, '') #=> 'def'

I want a short hand which is something like:

str = 'abcdef'
substr = 'abc'
str.lstrip(substr) #=> 'def'

Having similar argument for String#rstrip would be nice for symmetry although we already have String#chomp(substr)

My frequent use-case is coming from fluentd. We have remove_tag_prefix option to remove a heading substring from a tag. We currently using String#sub with a regular expression, but I feel regular expression matching is too much just to remove a heading substring. https://github.com/fluent/fluentd/blob/75005f18d48ed3d416890413fa5f83982b264c71/lib/fluent/compat/handle_tag_name_mixin.rb#L45


Related issues

Is duplicate of Ruby trunk - Feature #6842: Add Optional Arguments to String#stripAssigned

Associated revisions

Revision 59132
Added by sonots (Naotoshi Seo) 5 months ago

string.c: add String#delete_prefix and String#delete_prefix!
to remove leading substr [Feature #12694] [fix GH-1632]

  • string.c (rb_str_delete_prefix_bang): add a new method
    to remove prefix destuctively.

  • string.c (rb_str_delete_prefix): add a new method
    to remove prefix non-destuctively.

  • test/ruby/test_string.rb: add tests.

History

#1 [ruby-core:77020] Updated by nobu (Nobuyoshi Nakada) over 1 year ago

IIRC, there were proposals of lstrip and rstrip enhancement.
I'd expect them to accept char class(es), than a sub-string.

Note that rb_str_index_m accepts a Regexp too.
Calling str_strlen on it will segfault.

#2 [ruby-core:77021] Updated by sonots (Naotoshi Seo) over 1 year ago

Thanks, I found an issue which is 3 years old https://bugs.ruby-lang.org/issues/6842

#3 Updated by shyouhei (Shyouhei Urabe) over 1 year ago

  • Is duplicate of Feature #6842: Add Optional Arguments to String#strip added

#4 [ruby-core:77032] Updated by sonots (Naotoshi Seo) over 1 year ago

  • Status changed from Open to Rejected

I will continue this issue on https://bugs.ruby-lang.org/issues/6842, let me close.

=> https://bugs.ruby-lang.org/issues/6842 is too broad. Let us reopen this ticket, and talk about a way removing heading substr at this thread.

#5 [ruby-core:77174] Updated by sonots (Naotoshi Seo) about 1 year ago

  • Status changed from Rejected to Open

#6 [ruby-core:77175] Updated by mrkn (Kenta Murata) about 1 year ago

This method removes prefix string, so I propose remove_prefix or deprefix (means remove prefix).

#7 [ruby-core:77176] Updated by sonots (Naotoshi Seo) about 1 year ago

We discussed about this ticket on ruby development meeting.

Python lstrip http://www.tutorialspoint.com/python/string_lstrip.htm takes character classes as an argument, so providing a substring as an argument will introduce confusion.

We need to think of new naming. What about String#lchomp or String#remove_prefix or String#head_chop for example?

#8 [ruby-core:77177] Updated by sonots (Naotoshi Seo) about 1 year ago

It seems python, perl does not have similar methods (which removes heading substr)

#9 [ruby-core:77178] Updated by sonots (Naotoshi Seo) about 1 year ago

  • Description updated (diff)

#10 [ruby-core:77179] Updated by sonots (Naotoshi Seo) about 1 year ago

  • Description updated (diff)

#11 [ruby-core:77181] Updated by sonots (Naotoshi Seo) about 1 year ago

  • Description updated (diff)

#12 [ruby-core:77193] Updated by sonots (Naotoshi Seo) about 1 year ago

PHP has ltrim and rtrim (which is an alias of chop), but they are for removing a character list, not removing a substring http://php.net/manual/en/function.ltrim.php

ltrim('foaofe', 'foa'); #=> 'e'

Elixir has trim_leading, but it looks different with what we want to do http://elixir-lang.org/docs/stable/elixir/String.html#trim_leading/2

iex> String.trim_leading("__ abc _", "_")
" abc _"

iex> String.trim_leading("1 abc", "11")
"1 abc"

Golang has the same one with what we want to do https://golang.org/pkg/strings/#TrimPrefix and TrimSuffix

    var s = "Goodbye,, world!"
    s = strings.TrimPrefix(s, "Goodbye,") #=> , world

#13 [ruby-core:77258] Updated by duerst (Martin Dürst) about 1 year ago

Naotoshi Seo wrote:

Python lstrip http://www.tutorialspoint.com/python/string_lstrip.htm takes character classes as an argument, so providing a substring as an argument will introduce confusion.

"character classes" may be confusing. "a list of characters" might be more precise. There are many classes of characters that can't be expressed easily with a list. In particular because Python lstrip doesn't accept hyphens to group characters.

One way to deal with this would be to allow a Regexp that selects a single character, and apply this repeatedly. But we don't have any such concept yet.

#14 [ruby-core:81380] Updated by sonots (Naotoshi Seo) 6 months ago

I've created a PR https://github.com/ruby/ruby/pull/1632 with a name String#remove_prefix.
I will merge if the name is acceptable.

#15 [ruby-core:81486] Updated by znz (Kazuhiro NISHIYAMA) 6 months ago

str.sub(/^#{Regexp.escape(substr)}/, '') #=> 'def'

I think ^ should be \A in description of this ticket. (and maybe in handle_tag_name_mixin.rb of fluentd too)

Which is expected?: first prefix of string only or prefix of each line

#16 [ruby-core:81487] Updated by sonots (Naotoshi Seo) 6 months ago

\A is correct. I updated the description, thanks.

#17 Updated by sonots (Naotoshi Seo) 6 months ago

  • Description updated (diff)

#18 [ruby-core:81699] Updated by matz (Yukihiro Matsumoto) 5 months ago

I'd pick the name delete_prefix.

Matz.

#19 [ruby-core:81700] Updated by sonots (Naotoshi Seo) 5 months ago

Thanks! I've changed the name to delete_prefix. https://github.com/ruby/ruby/pull/1632

#20 [ruby-core:81712] Updated by Hanmac (Hans Mackowiak) 5 months ago

sonots (Naotoshi Seo) wrote:

Thanks! I've changed the name to delete_prefix. https://github.com/ruby/ruby/pull/1632

do we need a delete_suffix too or is that done via another method?

#21 [ruby-core:81713] Updated by sonots (Naotoshi Seo) 5 months ago

We have String#chomp to delete suffix, but it would be nice to have the method for symmetry.
I will create another thread to discuss about it.

#22 [ruby-core:81715] Updated by sonots (Naotoshi Seo) 5 months ago

I made a ticket for String#delete_suffix https://bugs.ruby-lang.org/issues/13665

#23 Updated by sonots (Naotoshi Seo) 5 months ago

  • Status changed from Open to Closed

Applied in changeset trunk|r59132.


string.c: add String#delete_prefix and String#delete_prefix!
to remove leading substr [Feature #12694] [fix GH-1632]

  • string.c (rb_str_delete_prefix_bang): add a new method
    to remove prefix destuctively.

  • string.c (rb_str_delete_prefix): add a new method
    to remove prefix non-destuctively.

  • test/ruby/test_string.rb: add tests.

Also available in: Atom PDF