在Emacs Lisp中,如何正确使用replace-regexp-in-string?

5

给定一个字符串,我希望能够将其中所有的链接替换为该链接的描述。例如,给定以下内容:

this is a [[http://link][description]]

我想要返回

this is a description

我使用re-builder构建了这个链接的正则表达式:

\\[\\[[^\\[]+\\]\\[[^\\[]+\\]\\]

这是我的函数:
(defun flatten-string-with-links (string)
    (replace-regexp-in-string "\\[\\[[^\\[]+\\]\\[[^\\[]+\\]\\]"
                (lambda(s) (nth 2 (split-string s "[\]\[]+"))) string))

它不是替换整个正则表达式序列,而是只替换尾部的“]]”。它产生的结果如下:

this is a [[http://link][descriptiondescription

我不明白出了什么问题。非常感谢任何帮助。
更新:我已经改进了链接的正则表达式。这与问题无关,但如果有人要复制它,他们可能会得到更好的版本。
1个回答

7
您的问题是split-string正在覆盖匹配数据,而replace-regexp-in-string依赖于该数据未被改变,因为它将使用该匹配数据来决定要剪切字符串的哪些部分。可以说这是一个文档错误,因为replace-regexp-in-string没有提到您的替换函数必须保留匹配数据。

您可以使用save-match-data进行解决,它是专门为此目的提供的宏:

(defun flatten-string-with-links (string)
    (replace-regexp-in-string "\\[\\[[a-zA-Z:%@/\.]+\\]\\[[a-zA-Z:%@/\.]+\\]\\]"
                (lambda (s) (save-match-data
                         (nth 2 (split-string s "[\]\[]+")))) string))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接