3

In my LaTeX code I want to replace these strings:

\left.\left.\left.
\left.\left.
\left.

with:

\left.\left.\left. \mycommand{3}
\left.\left. \mycommand{2}
\left. \mycommand{1}

where the argument of the command \mycommand is the number of the occurrences of the regexp `"\\left\." in each string.

My question is: can I obtain it by a query-replace? I figured out something like:

(query-replace-regexp "\\(\\(:?\\\\left\\.\\)+\\)"
                      `(,(lambda (x y)
                           (let* ((MATCH (match-string 0))
                                  (OCCURRENCES 
                                   (my-count-regexp "\\\\left\\."
                                                    MATCH))
                                  (OCCURRENCES (number-to-string OCCURRENCES)))
                             (concat MATCH "\\myfunction{" OCCURRENCES "}")))))

But I didn't find a function (my-count-regexp in my code) that returns the occurrences of a regexp in a string.

Also I'm not shure of the lambda function syntax.

Edit. I found that the following code works, but I'm still searching for something simplier:

(query-replace-regexp "\\(\\(:?\\\\left\\.\\)+\\)"
                      `(,(lambda (x y)
                           (let* ((MATCH (match-string 0))
                                  (OCCURRENCES
                                   (with-temp-buffer
                                     (insert MATCH)
                                     (goto-char (point-min))
                                     (count-matches "\\\\left\\.")))
                                  (MATCH (replace-regexp-in-string "\\\\"
                                                                   "\\\\\\\\" MATCH))

                                  (OCCURRENCES (number-to-string OCCURRENCES)))
                             (concat MATCH "\\\\myfunction{" OCCURRENCES "}")))))
Valeriy
  • 377
  • 4
  • 16
Gabriele Nicolardi
  • 1,199
  • 8
  • 17

2 Answers2

0

Why not derive the number of occurrences from the length of the match?

(let* ((match (match-string 0))
       (occurrences (/ (length match) 6))
       ...)
   ...)
Stefan
  • 26,154
  • 3
  • 46
  • 84
  • Because the matched string may be more complex (e.g. with some tab/space between the `\left.`s). I really need to count the matched regexp in a string. – Gabriele Nicolardi Dec 11 '19 at 19:08
0

I would approach it like this:

(goto-char (point-min))
(while (re-search-forward "\\(\\(\\\\left\\.\\)+\\)" nil t)
  (let ((s (match-beginning 0))
    (e (match-end 0))
    (m (match-string 0)))
  (cl--set-buffer-substring  s e
   (format "%s \\mycommand{%s}"
           m
           (count-matches "\\\\left" s e)))
  (goto-char e)))
John Kitchin
  • 11,555
  • 1
  • 19
  • 41