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 "}")))))

2 Answers 2

0

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

(let* ((match (match-string 0))
       (occurrences (/ (length match) 6))
       ...)
   ...)
1
  • 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. Dec 11, 2019 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)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.