0
ABC、DEF, GHI, JKL、MNO
PQR、STU, VWX、YZ

How do I replace all , s with in the repeated pattern above?

The repeated pattern can be mapped with the regex below:

"^\\([A-Z]+、\\)\\(\\([A-Z]+\\), \\)+"

However, because the , is a subset of group \\2, even though it can be separated from its preceding letters in the regex,

enter image description here

there is no way to replace it using replace-regexp without some form of nested group code. Also, DEF, doesn't seem the match like GHI, and STU, with the regex.

(replace-regexp "^\\([A-Z]+、\\)\\(\\([A-Z]+\\), \\)+" "\\1\\2、")

What's the right way to do this, then?


Update:

@jue's answer below resulted in this:

failed result

1 Answer 1

2

In elisp you normally search for what you're looking for in a loop, potentially establishing sub-groups of interest, and then you act on the match data if the search succeeded. Here you can simply replace every , with within the subgroup.

(save-excursion
  (while (re-search-forward "^[A-Z]+、\\(\\(?:[A-Z]+, \\)+\\)" nil t)
    (goto-char (match-beginning 1))
    (let ((bound (match-end 1)))
      (while (search-forward "," bound t)
        (replace-match "、")))))

Edit: Or more simply:

(save-excursion
  (while (re-search-forward "^[A-Z]+、" nil t)
    (while (re-search-forward "\\=\\([A-Z]+\\), " nil t)
      (replace-match "\\1、 "))))

That \= construct anchors the match to the current position of point, so that only the intended sequence of cases will be matched for that loop. Other options are supplying a BOUND argument to the search, or using narrowing to temporarily limit the searchable text.


Also, DEF, doesn't seem the match like GHI, and STU, with the regex.

That's because re-builder was highlighting the text which was referred to by back-reference \2 (being the ultimate match for that repeated subgroup) differently to the rest of the text. Try adding more matches for that group in a line, and it will become more obvious.

3
  • What if there are commas behind PQR、STU, VWX、YZ which I do not want to touch? For this is a simplification of Chinese bibliographic citations, APA style. A full citation looks like this: 鄧天珍、史少華, 白云星、方北松 (2019). 玉門花海畢家灘棺板《晉律注》保護修復. 江漢考古, (S1), 26–30. , which roughly translates to PQR、STU, VWX、YZ (2019). Title. Journal, (issue), 26-30.
    – Sati
    Oct 11, 2020 at 12:21
  • 1
    My answer was based on the case in your question. If you want to make more detailed replacements then the inner (while (search-forward ... might be a (while (re-search-forward with a more detailed search pattern, and you might be specifying a group in the replace-match call. As always in Emacs, read the help for the functions in question, or look them up in the manual.
    – phils
    Oct 11, 2020 at 12:30
  • I've added a simpler approach with a nested regexp search.
    – phils
    Oct 11, 2020 at 20:38

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.