Project

General

Profile

Feature #3388

regexp support for start_with? and end_with?

Added by trans (Thomas Sawyer) almost 9 years ago. Updated over 1 year ago.

Status:
Feedback
Priority:
Normal
Target version:
-
[ruby-core:30585]

Description

=begin
ruby-1.9.2-head > "aBcdeFghIj".start_with?(/abc/i)
=> false

In my implementation of start_with? it is easy enough to utilize #index, which works fine:

def start_with?(pattern)
index(pattern) == 0
end

But #end_with? is more difficult, and I had to use regular expressions.

 def end_with?(suffix)
   suffix = Regexp.escape(suffix) if String===suffix
   /#{suffix}$/.match(self) ? true : false
 end

However, we might get rid of the '? true : false' and return the MatchData, since that could be useful information.
=end


Files


Related issues

Related to Ruby trunk - Feature #13712: String#start_with? with regexpClosedActions
Has duplicate Ruby trunk - Bug #5536: String#start_with? and end_with? ignore arguments convertible to a String [PATCH]Closed11/01/2011Actions

History

#1

Updated by naruse (Yui NARUSE) almost 9 years ago

  • Status changed from Open to Rejected

=begin

=end

#2

Updated by nobu (Nobuyoshi Nakada) almost 9 years ago

=begin
Not a bug.
=end

#3

Updated by naruse (Yui NARUSE) almost 9 years ago

=begin
def end_with?(suffix)
if suffix.kind_of(String)
index(suffix) + suffix.length == self.length
else
m = suffix.match(self)
m ? m.post_match.empty? : false
end
end
=end

#4

Updated by marcandre (Marc-Andre Lafortune) almost 9 years ago

  • Category set to core

=begin
I'm moving this to the feature's tracker, since I feel it would make a valid addition.

PS: Yui, that code won't work:

 "Hello world. Bye".end_with? /e/ # => false

=end

#5

Updated by marcandre (Marc-Andre Lafortune) almost 9 years ago

  • Category set to core
  • Status changed from Rejected to Open
  • Target version set to 2.0.0

=begin

=end

#6

Updated by nobu (Nobuyoshi Nakada) almost 9 years ago

=begin
def start_with?(pattern)
!!rindex(pattern, 0)
end

def end_with(pattern)
rindex(pattern) and (!$& || $~.end(0) == length) or false
end

=end

#7

Updated by nobu (Nobuyoshi Nakada) almost 9 years ago

=begin
Missed.

def end_with?
i = rindex(pattern) and ($& ? $~.end(0) : i + pattern.length) == length or false
end

or

def end_with?(pattern)
if String === pattern
!!index(pattern, -pattern.length)
else
rindex(pattern) and $~.end(0) == length or false
end
end

=end

Updated by nahi (Hiroshi Nakamura) about 7 years ago

  • Description updated (diff)

rindex(pattern) would fail to detect proper end_of_string index. It must be /{suffix}\Z/.

Updated by akr (Akira Tanaka) about 7 years ago

I think we can cache regexp structure according to regexp source, options, encoding.

If regexp structure is cached, /\A#{pattern}/ and /#{pattern}\z/ is not slow for
second and successive dynamic regexp creation.

If it is not slow, we can use them to implement String#{start_with?,end_with?} for regexp.

Updated by mame (Yusuke Endoh) about 7 years ago

  • Status changed from Open to Feedback

A patch is welcome.

--
Yusuke Endoh mame@tsg.ne.jp

Updated by Eregon (Benoit Daloze) about 7 years ago

A patch is welcome.

I'm willing to give this a shot, but I think #5536 should be merged first.

Updated by Eregon (Benoit Daloze) over 6 years ago

Here is an attempt adding \A or \z to the Regexp's source and creating a new Regexp with it.
An alternative would be to call #to_s on the Regexp and add the anchor, but it seems cleaner to preserve options as global options.

What do you think?

akr: How would you cache the regexp structure?

Updated by ko1 (Koichi Sasada) over 6 years ago

  • Assignee set to naruse (Yui NARUSE)

Updated by Eregon (Benoit Daloze) over 6 years ago

I had a try implementing a global persistent cache for Regexps.

Is a global persistent cache OK? It seems bad for dynamically created regexps.
Maybe some kind of weak reference map?

akr: What kind of cache did you think to?

Updated by headius (Charles Nutter) over 6 years ago

JRuby currently does have a global cache for regexps. If you're interested, one of us can show you how it works.

Updated by Eregon (Benoit Daloze) over 6 years ago

headius (Charles Nutter) wrote:

JRuby currently does have a global cache for regexps. If you're interested, one of us can show you how it works.

Interesting. I see it's implemented using a SoftReference map.
I'm not aware of something similar in MRI.

If I read right, the only Regexp cache in MRI is a single last-used cache used in some String methods (match,scan,split,...).

It would be nice if we could differentiate static and dynamic regexps, but in any case I guess I could do a last-used cache as in re.c.

Updated by mame (Yusuke Endoh) over 6 years ago

  • Target version changed from 2.0.0 to 2.6

Updated by mame (Yusuke Endoh) over 1 year ago

After that, String#start_with? now accepts regexp (#13712). But end_with? does not support regexp yet because we don't have a direct use case for end_with? (and because of the difficulty of implementation).

#19

Updated by mame (Yusuke Endoh) over 1 year ago

#20

Updated by naruse (Yui NARUSE) over 1 year ago

  • Target version deleted (2.6)

Also available in: Atom PDF