Hello
Some time ago I've been needed something like
$foo =~ S/AB(.+?)CD//g; (1)
where AB and CD can be arbitrary strings.
To get this I've write the following.
(defun del-blk (s a b)
(let ((n (length s)))
(flet ((match (p s i)
(and (>= i (length p))
(string= s p :start1 (- i (length p)) :end1 i))))
(let ((x (loop
with pos
for i fixnum from 0 to n
if (match a s i) do (setq pos (- i (length a)))
else if (and (match b s i) pos)
collecting (cons pos i) and do (setf pos nil))))
(if (null x) s
(reduce #'(lambda (x y) (concatenate 'string x y))
(loop
with pos = 0 for (b . e) in (append
x (list (cons n 0)))
collecting (subseq s pos b) do (setf pos e))))))))
I call it the following way
* (del-blk "12<<ab>>34" "<<" ">>")
"1234"
*
Happened that I mentioned DEL-BLK in argue with Perl people.
They argue "we shouldn't do things being already implemented".
I've try to say "you don't know how they work" but seems w/o
much success. Also they add usually that development time is
valuable for them and they can't spend time to implementing
such things "manually".
So two my questions to you. How to implement DEL-BLK in
better way and 2) is it possible to say something more significant
opposite such arguments ?
--
Vladimir Zolotych ······@eurocom.od.ua
"Vladimir V. Zolotych" <······@eurocom.od.ua> writes:
> Hello
>
> I call it the following way
>
> * (del-blk "12<<ab>>34" "<<" ">>")
> "1234"
> *
>
> Happened that I mentioned DEL-BLK in argue with Perl people.
> They argue "we shouldn't do things being already implemented".
> I've try to say "you don't know how they work" but seems w/o
> much success. Also they add usually that development time is
> valuable for them and they can't spend time to implementing
> such things "manually".
>
> So two my questions to you. How to implement DEL-BLK in
> better way and 2) is it possible to say something more significant
> opposite such arguments ?
I don't know if this is better, but:
- it should be useable on any type of sequence
- it uses built-in (standard) functions
- it's shorter :-)
(defun del-blk (seq start-marker end-marker)
(let ((start (search start-marker seq)))
(when start
(let ((end (search end-marker seq
:start2 (+ start (length start-marker)))))
(when end
(return-from del-blk
(concatenate (type-of seq)
(subseq seq 0 start)
(subseq seq (+ end
(length end-marker)))))))))
seq) ; default return value: no match
Note: I'm slightly unhappy of the combination of nested
when's, return-from and a default return value. Suggestions for a more
elegant approach, anyone?
--
Raymond Wiker
·············@fast.no
Raymond Wiker wrote:
>
> "Vladimir V. Zolotych" <······@eurocom.od.ua> writes:
>
> > Hello
> >
> > I call it the following way
> >
> > * (del-blk "12<<ab>>34" "<<" ">>")
> > "1234"
> > *
> >
> > Happened that I mentioned DEL-BLK in argue with Perl people.
> > They argue "we shouldn't do things being already implemented".
> > I've try to say "you don't know how they work" but seems w/o
> > much success. Also they add usually that development time is
> > valuable for them and they can't spend time to implementing
> > such things "manually".
> >
> > So two my questions to you. How to implement DEL-BLK in
> > better way and 2) is it possible to say something more significant
> > opposite such arguments ?
>
> I don't know if this is better, but:
>
> - it should be useable on any type of sequence
>
> - it uses built-in (standard) functions
>
> - it's shorter :-)
>
> (defun del-blk (seq start-marker end-marker)
> (let ((start (search start-marker seq)))
> (when start
> (let ((end (search end-marker seq
> :start2 (+ start (length start-marker)))))
> (when end
> (return-from del-blk
> (concatenate (type-of seq)
> (subseq seq 0 start)
> (subseq seq (+ end
> (length end-marker)))))))))
> seq) ; default return value: no match
>
> Note: I'm slightly unhappy of the combination of nested
> when's, return-from and a default return value. Suggestions for a more
> elegant approach, anyone?
Here is an altermative you may like. Also note that I wouldn't use when w/ return-from, but rather I'd use if.
(defun del-blk (seq start-marker end-marker)
(let* ((start (search start-marker seq))
(end (and start (search end-marker seq
:start2 (+ start (length start-marker))))))
(if end
(concatenate (type-of seq)
(subseq seq 0 start)
(subseq seq (+ end (length end-marker))))
seq))) ; default return value: no match
Raymond Wiker <·············@fast.no> writes:
> (defun del-blk (seq start-marker end-marker)
> (let ((start (search start-marker seq)))
> (when start
> (let ((end (search end-marker seq
> :start2 (+ start (length start-marker)))))
> (when end
> (return-from del-blk
> (concatenate (type-of seq)
> (subseq seq 0 start)
> (subseq seq (+ end
> (length end-marker)))))))))
> seq) ; default return value: no match
If it was known that seq is a string, would it be worthwile to use
displaced array instead of subseq?
--
Janis Dzerins
If million people say a stupid thing it's still a stupid thing.