I forgot to mention that in order to be able to translate XPath to Smalltalk I added these methods to my Smalltalk: AbstractSequence>> afterSubCollection: aSequence [ifAbsent: exceptionBlock] "based on substring-after" beforeSubCollection: aSequence [ifAbsent: exceptionBlock] "based on substring-before"
I'm not going to display the code, which is pretty simple, because there is a serious efficiency problem with these. (The Java equivalent, had there been one, would not have had this problem, but since I think Java 7 it would too.) Imagine that we have a string consisting of N instances of separators, and we want to split it into pieces. [s includesSubCollection: separator] whileTrue: [ self process: (s beforeSubCollection: separator). s := s afterSubCollection: separator]. s isEmpty ifFalse: [ self process: s]. Do I need to explain why this takes O(N**2) time? However, r := ReadStream on: s. [r atEnd] whileFalse: [ self process: (r upToAll: separator)]. is linear time (assuming an efficient #upToAll:). My previous remarks about boundary issues apply here as well, of course. My previous remarks about wanting to see the context do too. On Sun, 2 Jun 2019 at 00:43, Ben Coman <b...@openinworld.com> wrote: > On Sat, 1 Jun 2019 at 18:01, Tim Mackinnon <tim@testit.works> wrote: > > > > Maybe this is a dumb question - and often I’m surprised when asking > these, but why is there no way to “find after” a string. > > > > I find it rather boring to try and parse a string, after a known marker > - thus: > > (loc := aString findString: ‘marker’) > 0 ifTrue: [ loc := loc + > ‘marker’ size ]. > > > > Is there a better way? This whole pattern seems very old and clunky and > not smalltalk like? > > > > Couldn’t we have: findAfter: aString ifAbsent: aBlock ? > > > > Or is there a whole better pattern for string searching that I’m missing > ? > > Can your input be split into tokens using Stirng>>findTokens: > and `ReadStream on: that`. Then you marker will be consumed by a single > #next. > > cheers -ben > >