emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: replace matches in any string


From: Stefan Monnier
Subject: Re: replace matches in any string
Date: Thu, 02 Sep 2010 18:21:22 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux)

> (let ((regex "\\(alpha\\)")
>       (string "gamma alpha beta"))
>   (when (string-match regex string)
>     (replace-match "[first greek letter \\1]" nil nil string 1)))
> -> "gamma [first greek letter alpha] beta"

> We want the equivalent but against any string, not just the original
> string (the `replace-match' docs say STRING has to be the one used for
> the original `string-match').  The use case is when you say to match X
> in an e-mail address, then set the target group to "something-X-other".
> We want to do it with regex "\\(X\\)" against "address@hidden" and
> target group "something-\\1-other".  Does that make sense?  Basically we
> want \1 but without the context of that original string we matched:

I think I'm beginning to understand.
First, you don't want

  (replace-match "[first greek letter \\1]" nil nil string 1)
but
  (replace-match "[first greek letter \\1]" nil nil string)

then second, you do get the behavior you want in the particular case
where the string-match matched the whole string.
So to simulate:

> (let ((regex "\\(alpha\\)")
>       (string "gamma alpha beta"))
>   (when (string-match regex string)
>     (our-new-function "found greek letter \\1")))
> -> "found greek letter alpha"

you'd want:

   (let ((regex "\\(alpha\\)")
         (string "gamma alpha beta"))
     (when (string-match (concat "\\`.*?\\(?:" regex "\\).*\\'") string)
       (replace-match "found greek letter \\1" nil nil string)))

will do what you want, assuming your strings don't contain newlines, and
assuming that providing `string' is not a problem.
Of course, such string matching is a bit less optimized (and even less
so if you replace "." with "\\(?:.\\|\n\\)" to handle newlines), so it
might not be ideal.

We could implement this feature efficiently by generalizing the `subexp'
argument so that rather than subgroup-number it can also take a special
new value `whole-string' which means "not just the whole matched text,
but the whole freakin' string".  Then you could do:

   (let ((regex "\\(alpha\\)")
         (string "gamma alpha beta"))
     (when (string-match regex string)
       (replace-match "found greek letter \\1" nil nil string 'whole-string)))


-- Stefan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]