From: Ramon M. Felciano
Subject: Doing a grep-like search-and-replace in lisp?
Date: 
Message-ID: <felciano-1512952008160001@smi-mac-146.stanford.edu>
Hello --

I'm trying to do a parameterized search-and-replace on a string in lisp,
and would like to know if there is a simple way of doing it (i.e. w/out
writing my own routine that walks the string character by character).

The search needs to be parameterized in the sense that certain wildcards
in the search pattern will need to be in the replace patter as well. I
want something like this:

(replace my-string "Length: @1 feet" "Approx length: @1 ft")

The idea is to replace a set of start-tag / end-tag occurences with
another start-tag / end-tag pattern, keeping the data in the middle the
same. Perl does this nicely; I haven't found an equivalent in lisp. Any
suggestions (I'm using MCL 3.0).

Thanks!

Ramon

-------------------------------------o-------------------------------------
                  Ramon M. Felciano  |  voice: (415) 725-3398
     Section on Medical Informatics  |  ········@camis.stanford.edu
           http://camis.stanford.edu/people/felciano/index.html
-------------------------------------o------------------------------------- 

From: Ken Anderson
Subject: Re: Doing a grep-like search-and-replace in lisp?
Date: 
Message-ID: <KANDERSO.95Dec16175459@lager.bbn.com>
In article <·························@smi-mac-146.stanford.edu> ········@camis.stanford.edu (Ramon M. Felciano) writes:

 
 I'm trying to do a parameterized search-and-replace on a string in lisp,
 and would like to know if there is a simple way of doing it (i.e. w/out
 writing my own routine that walks the string character by character).
 
 The search needs to be parameterized in the sense that certain wildcards
 in the search pattern will need to be in the replace patter as well. I
 want something like this:
 
 (replace my-string "Length: @1 feet" "Approx length: @1 ft")
 
 The idea is to replace a set of start-tag / end-tag occurences with
 another start-tag / end-tag pattern, keeping the data in the middle the
 same. Perl does this nicely; I haven't found an equivalent in lisp. Any
 suggestions (I'm using MCL 3.0).
 
Try the lisp repository the is an nregx file that does some regular
expression matching.  However, the following works for the above example:

(defun replace (my-string left-1 right-1 left-2 right-2)
  (let ((left (search left-1 my-string)))
    (if left
	(let* ((start2 (+ left (length left-1)))
	      (right (search right-1 my-string :start2 start2 :from-end t)))
	  (if right 
	      (concatenate 'string (subseq my-string 0 left)
				  left-2
				  (subseq my-string start2 right)
				  right-2)

	    my-string))
      my-string)))
  
USER(282): (replace "with results of Length: 23.5 feet"
		    "Length: "
		    " feet"
		    "Approx length: "
		    " ft")
"with results of Approx length: 23.5 ft"
[Current process: *lisp-listener*]
USER(283): 
From: Barry Margolin
Subject: Re: Doing a grep-like search-and-replace in lisp?
Date: 
Message-ID: <4avdp4$gq@tools.bbnplanet.com>
In article <·························@smi-mac-146.stanford.edu>,
Ramon M. Felciano <········@camis.stanford.edu> wrote:
>I'm trying to do a parameterized search-and-replace on a string in lisp,
>and would like to know if there is a simple way of doing it (i.e. w/out
>writing my own routine that walks the string character by character).

While there are no standard functions for doing search and replace in one
step, you don't have to do a character-by-character search.  You can use
the function SEARCH to find the location of a substring within a string,
and CONCATENATE to construct the result.

>The search needs to be parameterized in the sense that certain wildcards
>in the search pattern will need to be in the replace patter as well. I

If wildcards are involved, you're going to have to do some parsing of the
expressions, and more complex searching of the target string.  In general,
this kind of stuff isn't found built into most languages, except those
designed specifically for pattern processing (e.g. perl and SNOBOL).
Common Lisp has a full suite of *string-processing* functions, but nothing
specifically for *pattern processing*.

There may be some PD libraries that implement this, though; check the Lisp
Repository (the location is in the FAQ).
-- 
Barry Margolin
BBN PlaNET Corporation, Cambridge, MA
······@bbnplanet.com
Phone (617) 873-3126 - Fax (617) 873-6351
From: k p c
Subject: Re: Doing a grep-like search-and-replace in lisp?
Date: 
Message-ID: <1995Dec17.045817.12000@ptolemy-ethernet.arc.nasa.gov>
CL is worth using, but CL regexp capabilities are behind the times.

	o There are regexp-like pattern-replacement packages in the archive
	o I think GCL has regexps now
	o You can use foreign functions
	o You can use a CL regexp package from the archive
	o There are string and vector functions in CL
	o You can call a program to do the regexp parsing

IMHO a well-thought-out efficient regexp facility should be part of
the CL standard (that'll draw flames.  :-)).

If you post a followup to this article, I would appreciate a courtesy
verbatim copy by email to help work around potentially unreliable feeds.

---
···@ptolemy.arc.nasa.gov.  AI, multidisciplinary neuroethology, info filtering.
Play fairly; offer takebacks; connect edge with center; neither play too thinly
nor engage too readily; take stones early; divide and conquer; don't allow them
to invade; pick your battles; see the whole board; use solid connections; grow.
From: Joe User
Subject: Re: Doing a grep-like search-and-replace in lisp?
Date: 
Message-ID: <4b2j3o$igr@klein.delphi.com>
········@camis.stanford.edu (Ramon M. Felciano) wrote:
>I'm trying to do a parameterized search-and-replace on a string in lisp,
>and would like to know if there is a simple way of doing it (i.e. w/out
>writing my own routine that walks the string character by character).

In SIOD I've been using calls to the unix/posix regcomp and regexec
subroutines a lot lately. (ftp://ftp.std.com/pub/gjc/siod_tar.gz, is
an interim release, please forgive the OSF/1'isms in it, if any).

You (define *pat* (regcomp "regular-expression" REG_EXTENDED)) 
then (let ((match (regexec *pat* "string")))
       (cond ((pair? match)
               ...)
             ('else-no-match ...)))

regexec returning an alist with ((<start> . <end>) ...) of the parts
of the string that match parts of the regular expression pattern.
You end up mapcar'ing down the match list, breaking up the string
and doing whatever you want with the result.

At least in OSF/1 (DIGITAL UNIX) the regcomp/regex routines are
exactly what grep and awk use.

Posix standardization seems to be forcing a lot of useful functionality
into subroutine libraries, which is certainly nice for the benefit of
other languages.

-gjc