在emacs的"自定义"模式下,需要多少反斜杠来逃避正则表达式?

Bri*_*ell 9 regex emacs elisp backslash

我正在尝试使用emacs的customize-group软件包来调整我的设置的某些部分,而且我受到了阻碍.在使用自定义进行更改后,我在.emacs文件中看到类似这样的内容:

'(tramp-backup-directory-alist (quote (("\\\\`.*\\\\'" . "~/.emacs.d/autobackups"))))
Run Code Online (Sandbox Code Playgroud)

这是将以下内容放入自定义文本字段的结果:

Regexp matching filename: \\`.*\\'
Run Code Online (Sandbox Code Playgroud)

这是一个有代表性的例子:我实际上试图改变一些想要正则表达式的东西,它们都显示出同样的问题.有多少层报价,真的吗?我似乎无法找到神奇的反斜杠数来获得我所要求的gosh-dang事情,即使对于最简单的正则表达式也是如此.*.现在,给定的定制产生 - 没有.它没有改变emacs的默认行为.

更好的是,这在哪里记录了?谷歌有点困难,但我在那里以及官方文档和Emacs维基中都尝试过很多东西.在自定义模式下,需要在正常表达式中生成多少副本反斜杠的权威来源实际上是什么工作 - 或者至少是因为某种警告失败而不是默默地失败?


编辑:正如经常在愤怒中提出的问题一样,我问的是错误的问题.幸运的是,下面的答案让我得到了我需要的问题的答案,这是关于引用规则的.我将尝试写下我在这里学到的内容,因为我发现文档和Googleable资源令人抓狂.所以这里是我通过反复试验找到的引用规则,我希望他们帮助别人,激励纠正,或两者兼而有之.

当emacs自定义模式缓冲区要求您提供"正则表达式匹配文件名"时,正如emacs经常出现的那样,它既简洁又特殊(创作者的个性多久被赋予创作!).一方面,这意味着一个正则表达式将与搜索匹配项的文件的整个路径进行比较,而不仅仅是文件本身的名称,正如您可能从术语"文件名"中所假设的那样.例如,这与emacs buffer-file-name函数中使用的"文件名"相同.

此外,虽然如果你放入foo字段,你会看到"foo"(用双引号)写入实际文件,这是不够引用而不是正确的引用.你需要引用你的正则表达式,引用样式,据我所知,只有emacs使用:``backtick-foo-single-quote'`scheme.然后你需要逃避它,制作它\`backslash-backtick-foo-backslash-single-quote\'(如果你认为在Markdown中输入是一件令人头痛的话,那么在emacs中更是如此).

除此之外,emacs似乎有一个规则,即正则.表达式特殊字符/与文件名的开头不匹配,因此,正如我上面发生的那样,经典.*模式似乎没有任何匹配:匹配"所有文件" ,你实际上需要正则表达式/.*,然后你填写自定义模式的报价格式来生成\`/.*\',之后自定义绘制另一层转义到它并将其写入自定义文件.

我的一个努力的最终结果 - 一个设置,使#autosave#文件不会使你正在工作的目录嘎嘎作响,而是所有人都住在一个地方:

(custom-set variables
  '(auto-save-file-name-transforms (quote (
    ("\\`/[^/]*:\\([^/]*/\\)*\\([^/]*\\)\\'" "~/.emacs.d/autobackups/\\2" t)
    ("\\`/.*/\\(.*?\\)\\'" "~/.emacs.d/autobackups/\\1" t)
))))
Run Code Online (Sandbox Code Playgroud)

elisp的反斜杠对你的理智的威胁远大于括号.


编辑2:我再次出错的时候了.我终于找到了相关的文档(当然是通过阅读另一个Stack Overflow问题!):Regexp Backslash Constructs.对我来说困惑的关键点:反引号和单引号在这种情况下没有引用:它们相当于perl ^$特殊字符.反斜杠后缀构造匹配锚定在要检查匹配的字符串开头的空字符串,反斜杠 - 单引号构造匹配未考虑字符串末尾的空字符串.并且通过"正在考虑的字符串",我的意思是"缓冲区,在这种情况下恰好只包含一个文件路径,但如果你想要匹配,你需要匹配整个dang事物,因为这是elisp的全局正则表达式行为".

向上帝发誓,就像处理外星文明一样.


编辑3:为了避免混淆未来的读者 -

  • \`是"缓冲区的开头"的emacs正则表达式.(参见Perl's\A)
  • \'是"缓冲区结束"的emacs正则表达式.(参见Perl's \Z)
  • ^是"行的开头"的常用成语正则表达式.它可以在emacs中使用.
  • $是"行尾"的常用成语正则表达式.它可以在emacs中使用.

因为在多行文本中使用正则表达式搜索文本在emacs中比在其他地方更常见(例如M-x occur),所以在emacs中使用反引号和单引号特殊字符,并且尽我所知,它们在上下文中使用自定义模式,因为如果您正在考虑自定义模式字段的通用未知输入,它可能包含换行符,因此您希望使用缓冲区开头和缓冲区结束特殊字符,因为它的开头和结尾输入不保证是一行的开头和结尾.

我不确定是否后悔劫持我自己的Stack Overflow问题,并将其转化为博客文章.

san*_*inc 3

在自定义字段中,您可以根据此处描述的语法输入正则表达式。当customize将正则表达式写入字符串时,正则表达式中的任何反斜杠或双引号字符都将按照常规字符串转义约定进行转义。

简而言之,只需在正则表达式字段中输入单个反斜杠,它们就会在写入custom-set-variables您的.emacs.

另外:由于您的正则表达式用于匹配文件名,因此您可以尝试打开一个包含您想要匹配的文件的目录,然后运行M-x re-builder RET​​. 然后,您可以以字符串转义格式输入正则表达式,以确认它与这些文件匹配。通过% m在 dired 缓冲区中输入,您可以输入非转义格式的正则表达式(即,就像在自定义字段中一样),并且 dired 将标记匹配的文件名。