help-gnu-emacs
[Top][All Lists]
Advanced

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

Re: Tricky Regexp - How to insert a marker every 3rd number in a sequenc


From: gnu ist
Subject: Re: Tricky Regexp - How to insert a marker every 3rd number in a sequence that begins with a certain delimiter
Date: Sat, 6 Jun 2015 17:57:09 -0700

On Saturday, June 6, 2015 at 10:44:55 AM UTC-7, gnui...@gmail.com wrote:
> tricky regexp
>
> How to insert a marker every 3rd number in a sequence that begins with a
certain delimiter, and ends with a certain delimiter and its length is a
multiple of three?
>
> I want to isolate sequences like this in a text and to work on them only.
>
> Given:-
>
> text
> text
> BEGIN N N N END
> text BEGIN N N N N N N END
> some text BEGIN N N N N N N N N N END
> text
> N N N N N N N
> text
>
> The sequences I want to work on start with BEGIN and end with END with
exact multiple of 3 B's in between with only single space. I want to place
a newline before every 3 B's. So the above text would transform to
>
> text
> text
> BEGIN
> N N N
> Z
> text BEGIN
> N N N
> N N N
> Z
> some text BEGIN
> N N N
> N N N
> N N N
> Z
> text
> N N N N N N N
> text
>
>
> More accurately, in a "BEGIN N N N N N N N N N END" type sequence, I want
to insert a \n before every N whose cardinality is 3n where n=0,1,2,... and
the first N has cardinality 0. I also want to insert a \n righ before such
a END.
>
>
> My efforts:
>
> (replace-regexp "BEGIN \\([0-9]\\) \\([0-9]\\) \\([0-9]\\) END" "BEGIN
\n\\1 \\2 \\3 \nEND")

Ok, your replies are quite helpful.

Now, lets focus on this part.

          (while (looking-at "\\(^\\| \\)N N N\\( \\|$\\)")
            (goto-char (match-end 0))
            (delete-horizontal-space t)
            (insert "\n"))


This successfully adds the newlines every three N's and is equivalent to
John Mastro's if I use replace-regexp-in-string and it allows me to refer
to the first three as \\1 \\2 \\3 while the outer re-search-forward as
(match-string 0).

A further problem is that I need to take the average of the first two N's
and last two N's and replace the first by the first average and last by the
second average leaving the middle N as it is.

Unfortunately, the problem is that within re-search-forward, replace-match
can reference tagged-groups as (match-string 2) etc but to do an eval for
replace-match and get the indefinite string "N N N ..." which is equivalent
to John Mastro's if I use replace-regexp-in-string.
but if you want to an arithmetic on this I am getting a problem. The
snippet is

(replace-match   (replace-regexp-in-string "\\([0-9.]+\\) \\([0-9.]+\\)
\\([0-9.]+\\)"
(concat "\n" (format "%s " (string-to-number "\\1")) "\\2" .....))

The second \\2 is correctly replaced by its string value, but the first by
two inverse transformations is not. \\2 is just inside a function (concat)
while \\1 is a second level.

The error is that the value of \\1 is just zero. If I replace \\1 by lets
say 6 then I get the correct answer.


reply via email to

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