Feature Requests item #1190701, was opened at 2005-04-26 20:35 Message generated for change (Comment added) made by cxdunn You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=355470&aid=1190701&group_id=5470
Category: Python Library Group: None Status: Open Resolution: None Priority: 5 Submitted By: Christopher Dunn (cxdunn) Assigned to: Nobody/Anonymous (nobody) Summary: Add 'before' and 'after' methods to Strings Initial Comment: GNU String used to have two very useful methods, 'before' and 'after'. These are so useful I keep them defined in an __init__.py file. (Unfortunately, I do not know how to make them methods, instead of global functions.) Usage: >>> "root.sub".before(".") 'root' >>> "root.sub1.sub2".after("root.sub1") '.sub2' They work like s.split(word)[0], and s.split(word)[-1], but they are so intuitive they ought to be part of the interface. I'm not sure whether they should raise exceptions on failure, or simply return the whole string. -cxdunn ---------------------------------------------------------------------- >Comment By: Christopher Dunn (cxdunn) Date: 2005-04-28 01:50 Message: Logged In: YES user_id=1267419 Your examples prove my point:: >>> s = "Monty.Python" >>> t = "fubar" >>> s[:s.find(t)] 'Monty.Pytho' >>> s[s.find(t)+len(t):] 'y.Python' Of course, this would work: >>> s.split(t)[0] 'Monty.Python' >>> s.split(t)[-1] 'Monty.Python' That is not terrible, but the behavior I want is actually more like strip()/rstrip():: def before( s, first ): """Find first inside string s and return everything before that. >>> before('xyz.pdq.abc', '.') 'xyz' >>> before('xyz.pdq.abc', 'fubar') 'xyz.pdq.abc' """ return s.split(first)[0] def after( s, first ): """Find first inside string s and return everything after that. >>> after('xyz.pdq.abc', '.') 'pdq.abc' >>> after('xyz.pdq', 'xyz.') 'pdq' >>> after('xyz.pdq.abc', 'fubar') '' """ return first.join(s.split(first)[1:]) def rbefore( s, last ): """Find last inside string s, from the right, and return everything before that. >>> rbefore('xyz.pdq.abc', '.') 'xyz.pdq' >>> rbefore('xyz.pdq.abc', 'fubar') '' """ return last.join(s.split(last)[:-1]) def rafter( s, last ): """Find last inside string s, from the right and return everything after that. >>> rafter('xyz.pdq.abc', '.') 'abc' >>> rafter('xyz.pdq.abc', 'fubar') 'xyz.pdq.abc' """ return s.split(last)[-1] Besides, it's a question of elegance. These are very useful little functions, which look wonderful as methods of string, and the on-the-fly solutions are prone to error. Reconsider? If not, I'll just post it to the Cookbook (without your name -- I'm not trying to embarrass anyone) to point out the danger of relying on string.find(). -cxdunn ---------------------------------------------------------------------- Comment By: Christopher Dunn (cxdunn) Date: 2005-04-28 01:40 Message: Logged In: YES user_id=1267419 Your examples prove my point: >>> s = "root.sub" >>> t = "fubar" >>> s[:s.find(t)] 'root.su' >>> s = "root.sub1.sub2" >>> t = "fubar" >>> s[s.find(sep)+len(sep):] '.sub1.sub2' string.find() is the wrong way. I can live with string.split(): >>> "root.sub1.sub2" >>> t = '.' >>> s.split(t)[0] 'root' >>> s.split(t)[-1] 'sub2' >>> t = "fubar" >>> s.split(t)[0] 'root.sub1.sub2' >>> s.split(t)[-1] 'root.sub1.sub2' This is not terrible, but the desired behavior is really more like strip/rstrip:: def before( s, first ): """Find first inside string s and return everything before that. >>> before('xyz.pdq.abc', '.') 'xyz' >>> before('xyz.pdq.abc', 'fubar') 'xyz.pdq.abc' """ return s.split(first)[0] def after( s, first ): """Find first inside string s and return everything after that. >>> after('xyz.pdq.abc', '.') 'pdq.abc' >>> after('xyz.pdq', 'xyz.') 'pdq' >>> after('xyz.pdq.abc', 'fubar') '' """ return first.join(s.split(first)[1:]) def rbefore( s, last ): """Find last inside string s, from the right, and return everything before that. >>> rbefore('xyz.pdq.abc', '.') 'xyz.pdq' >>> rbefore('xyz.pdq.abc', 'fubar') '' """ return last.join(s.split(last)[:-1]) def rafter( s, last ): """Find last inside string s, from the right and return everything after that. >>> rafter('xyz.pdq.abc', '.') 'abc' >>> rafter('xyz.pdq.abc', 'fubar') 'xyz.pdq.abc' """ return s.split(last)[-1] It's a question of elegance. These are very useful, infuitive functions, and I cannot add them to string myself. And as you've seen, it's easy to create bugs when you try to do this on the fly. Reconsider? If not, I'll just post it in the Cookbook, to point out the dangers of relying on string.find. ---------------------------------------------------------------------- Comment By: Raymond Hettinger (rhettinger) Date: 2005-04-28 00:15 Message: Logged In: YES user_id=80475 I'm -1 on expanding the string API for something so easily coded with existing primitives: >>> s = "root.sub" >>> t = "." >>> s[:s.find(t)] 'root' >>> s = "root.sub1.sub2" >>> t = "root.sub1" >>> s[s.find(sep)+len(sep):] 'sub1.sub2' ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=355470&aid=1190701&group_id=5470 _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com