【发布时间】:2011-11-12 07:24:21
【问题描述】:
我正在尝试使用 emacs 的 customize-group 软件包来调整我的设置的某些部分,但我遇到了困难。使用自定义进行更改后,我在 .emacs 文件中看到类似的内容:
'(tramp-backup-directory-alist (quote (("\\\\`.*\\\\'" . "~/.emacs.d/autobackups"))))
这是将以下内容放入自定义文本字段的结果:
Regexp matching filename: \\`.*\\'
这是一个有代表性的示例:我实际上是在尝试更改需要正则表达式的几个东西,它们都显示出同样的问题。真的有多少层引用?即使对于像.* 这样最简单的正则表达式,我似乎也找不到反斜杠的神奇数量来让gosh-dang 做我要求它做的事情。现在,给定的定制产生 - 没有。它不会改变 emacs 的默认行为。
更好的是,这到底是在哪里记录的?这对谷歌来说有点困难,但我已经在那里以及官方文档和 Emacs wiki 中尝试了很多东西。哪里有权威的来源,说明需要多少个 dang 反斜杠才能使自定义模式下的正则表达式真正起作用 - 或者至少,失败并发出某种警告而不是静默失败?
编辑: 就像在愤怒中提出问题时经常发生的那样,我问错了问题。幸运的是,下面的答案让我找到了我需要的问题的答案,即关于引用规则的问题。我将尝试写下我在这里学到的东西,因为我发现文档和 Googleable 资源对此非常晦涩难懂。所以这里是我通过反复试验找到的引用规则,我希望它们可以帮助别人,激发纠正,或两者兼而有之。
当 emacs 自定义模式缓冲区要求您提供“正则表达式匹配文件名”时,它就像 emacs 通常一样,既简洁又独特(the creator's personality 被赋予创建的频率!)。这意味着,一方面,一个正则表达式将与文件的 整个路径 进行比较以搜索匹配项,而不仅仅是与您可能从术语“文件名”。例如,这与 emacs 的 buffer-file-name 函数中使用的“文件名”含义相同。
此外,尽管如果您将foo 放在该字段中,您会看到"foo"(带有双引号)写入实际文件,这还不够引用,也不是正确的引用。您需要使用引用样式引用您的正则表达式,据我所知,只有 emacs 使用:“backtick-foo-single-quote”方案。然后您需要转义它, 将其设为\`backslash-backtick-foo-backslash-single-quote\'(如果您认为在 Markdown 中输入令人头疼,那么在 emacs 中更是如此)。
除此之外,emacs 似乎有一条规则,即 . 正则表达式特殊字符与文件名开头的 / 不匹配,因此,正如上面发生在我身上的那样,经典的 .* 模式似乎什么都不匹配:要匹配“所有文件”,您实际上需要正则表达式/.*,然后将其填充到customize-mode的引用格式中以生成\`/.*\',然后自定义绘制另一个 em> 转义层并将其写入自定义文件。
我的一项努力的最终结果是这样一种设置,即 #autosave# 文件不会占用您正在工作的目录,而是全部存在于一个地方:
(custom-set variables
'(auto-save-file-name-transforms (quote (
("\\`/[^/]*:\\([^/]*/\\)*\\([^/]*\\)\\'" "~/.emacs.d/autobackups/\\2" t)
("\\`/.*/\\(.*?\\)\\'" "~/.emacs.d/autobackups/\\1" t)
))))
elisp 中的反斜杠对您的理智的威胁远大于括号。
编辑 2:是时候让我再次犯错了。我终于找到了相关文档(当然是通过阅读another Stack Overflow question!):Regexp Backslash Constructs。对我来说混淆的关键点:反引号和单引号在这种情况下 not 引用:它们相当于 perl 的 ^ 和 $ 特殊字符。反斜杠反引号构造匹配锚定在正在检查匹配的字符串开头的空字符串,反斜杠单引号构造匹配正在考虑的字符串末尾的空字符串。 “正在考虑的字符串”是指“缓冲区,在这种情况下恰好只包含一个文件路径,但是如果你想要匹配的话,你需要匹配整个 dang 的东西,因为这是 elisp 的全局正则表达式行为。”
向上帝发誓,这就像与外星文明打交道。
EDIT 3:为了避免混淆未来的读者 -
-
\`是“缓冲区开头”的 emacs 正则表达式。 (参见Perl's\A) -
\'是“缓冲区结束”的 emacs 正则表达式。 (参见 Perl 的\Z) -
^是“行首”的常用成语正则表达式。它可以在 emacs 中使用。 -
$是“行尾”的常用成语正则表达式。它可以在 emacs 中使用。
因为跨多行文本的正则表达式搜索在 emacs 中比在其他地方更常见(例如M-x occur),所以在 emacs 中使用了反引号和单引号特殊字符,据我所知,它们'在自定义模式的上下文中重新使用,因为如果您正在考虑自定义模式字段的通用未知输入,它可能包含换行符,因此您希望使用缓冲区开头和缓冲区结尾特殊字符,因为input 的开头和结尾不保证是 line 的开头和结尾。
我不确定是否会后悔劫持我自己的 Stack Overflow 问题并将其实质上变成了一篇博文。
【问题讨论】:
-
回答“到达 troff 宏的中心需要多少次反斜杠”和“到达 tootsie-roll pop 的中心需要多少次舔?”是一样的:继续尝试直到它起作用。 :)
-
+1 坚持下去并与世界其他地方分享您的发现! :)
标签: regex emacs elisp backslash