简体   繁体   English

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

[英]How many backslashes are required to escape regexps in emacs' “Customize” mode?

I'm trying to use emacs' customize-group packages to tweak some parts of my setup, and I'm stymied. 我正在尝试使用emacs的customize-group软件包来调整我的设置的某些部分,而且我受到了阻碍。 I see things like this in my .emacs file after I make changes with customize: 在使用自定义进行更改后,我在.emacs文件中看到类似这样的内容:

'(tramp-backup-directory-alist (quote (("\\\\`.*\\\\'" . "~/.emacs.d/autobackups"))))

This was the result of putting the following into the customize text field: 这是将以下内容放入自定义文本字段的结果:

Regexp matching filename: \\`.*\\'

This is a representative sample: I'm actually trying to change several things that want a regexp, and they all show this same problem. 这是一个有代表性的例子:我实际上试图改变一些想要正则表达式的东西,它们都显示出同样的问题。 How many layers of quoting are there, really? 有多少层报价,真的吗? I can't seem to find the magic number of backslashes to get the gosh-dang thing to do what I'm asking it to, even for the simplest regular expressions like .* . 我似乎无法找到神奇的反斜杠数来获得我所要求的gosh-dang事情,即使是最简单的正则表达式,如.* Right now, the given customization produces - nothing. 现在,给定的定制产生 - 没有。 It makes no change from emacs' default behavior. 它没有改变emacs的默认行为。

Better yet, where on earth is this documented? 更好的是,这在哪里记录了? It's a little difficult to Google for, but I've been trying quite a few things there as well as in the official documentation and the Emacs wiki. 谷歌有点困难,但我在那里以及官方文档和Emacs维基中都尝试过很多东西。 Where is an authoritative source for how many dang backslashes one needs to make a regular expression in customize-mode actually work - or at the very least, to fail with some kind of warning instead of failing silently? 在自定义模式下,需要在正常表达式中使用多少副反斜杠的权威来源实际工作 - 或者至少是以某种警告而不是默默地失败?


EDIT: As so often happens with questions asked in anger, I was asking the wrong question. 编辑:正如经常在愤怒中提出的问题一样,我问的是错误的问题。 Fortunately the answers below, led me to the answer to the question that I needed, which was about quoting rules. 幸运的是,下面的答案让我得到了我需要的问题的答案,这是关于引用规则的。 I'm going to try to write down what I learned here, because I find the documentation and Googleable resources to be maddeningly obscure about this. 我将尝试写下我在这里学到的内容,因为我发现文档和Googleable资源令人抓狂。 So here are the quoting rules I found by trial and error, and I hope that they help someone else, inspire correction, or both. 所以这里是我通过反复试验找到的引用规则,我希望他们帮助别人,激励纠正,或两者兼而有之。

When an emacs customize-mode buffer asks you for a "Regexp matching filename", it is being, as emacs often is, both terse and idiosyncratic (how often the creator's personality is imparted to the creation!). 当emacs自定义模式缓冲区要求您提供“正则表达式匹配文件名”时,正如emacs经常出现的那样,它既简洁又特殊( 创作者的个性多久被赋予创作!)。 It means, for one thing, a regexp that will be compared to the whole path of the file in search of a match, not just to the name of the file itself as you might assume from the term "filename". 一方面,这意味着一个正则表达式将与搜索匹配项的文件的整个路径进行比较,而不仅仅是文件本身的名称,正如您可能从术语“文件名”中所假设的那样。 This is the same sense of "filename" used in emacs' buffer-file-name function, for example. 例如,这与emacs的buffer-file-name函数中使用的“filename”相同。

Further, although if you put foo in the field, you'll see "foo" (with double-quotes) written to the actual file, that's not enough quoting and not the right quoting. 此外,虽然如果你把foo放在字段中,你会看到写入实际文件的"foo" (带双引号),这不足以引用而不是正确的引用。 You need to quote your regexp with the quoting style that, as far as I can tell, only emacs uses: the ``backtick-foo-single-quote'`scheme. 你需要引用你的正则表达式,引用样式,据我所知,只有emacs使用:``backtick-foo-single-quote'`scheme。 And then you need to escape that, making it \\`backslash-backtick-foo-backslash-single-quote\\' (and if you think that's a headache to input in Markdown, it's more so in emacs). 然后你需要逃避它,使它成为\\`backslash-backtick-foo-backslash-single-quote\\' (如果你认为在Markdown输入是一件令人头疼的事情,那么在emacs中更是如此)。

On top of this, emacs appears to have a rule that the . 除此之外,emacs似乎有一个规则. regexp special character does not match a / at the beginning of filenames, so, as was happening to me above, the classic .* pattern will appear to match nothing: to match "all files", you actually need the regexp /.* , which then you stuff into the quote format of customize-mode to produce \\`/.*\\' , after which customize paints another layer of escaping onto it and writes it to the customization file. regexp特殊字符与文件名开头的/不匹配,因此,正如我上面发生的那样,经典的.*模式似乎没有任何匹配:为了匹配“所有文件”,你实际上需要regexp /.* ,然后你\\`/.*\\'自定义模式的报价格式来生成\\`/.*\\' ,然后自定义绘制另一层转义到它并将其写入自定义文件。

The final result for one of my efforts - a setting such that #autosave# files don't gunk up the directory you're working in, but instead all live in one place: 我的一个努力的最终结果 - 一个设置,使#autosave#文件不会使你正在工作的目录变得无效,而是所有人都住在一个地方:

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

Backslashes in elisp are a far greater threat to your sanity than parentheses. elisp的反斜杠对你的理智的威胁远大于括号。


EDIT 2 : Time for me to be wrong again. 编辑2 :我再次出错的时候了。 I finally found the relevant documentation (through reading another Stack Overflow question , of course!): Regexp Backslash Constructs . 我终于找到了相关的文档(当然是通过阅读另一个Stack Overflow问题 !): Regexp Backslash Constructs The crucial point of confusion for me: the backtick and single quote are not quoting in this context: they're the equivalent of perl's ^ and $ special characters. 对我来说困惑的关键点:反引号和单引号在这个上下文中没有引用:它们相当于perl的^$特殊字符。 The backslash-backtick construct matches an empty string anchored at the beginning of the string being checked for a match, and the backslash-single-quote construct matches the empty string at the end of the string-under-consideration. 反斜杠后缀构造匹配锚定在要检查匹配的字符串开头的空字符串,反斜杠 - 单引号构造匹配未考虑字符串末尾的空字符串。 And by "string under consideration," I mean "buffer, which just happens to contain only a file path in this case, but you need to match the whole dang thing if you want a match at all, since this is elisp's global regexp behavior." 并且通过“正在考虑的字符串”,我的意思是“缓冲区,在这种情况下恰好只包含一个文件路径,但如果你想要匹配,你需要匹配整个dang事物,因为这是elisp的全局正则表达式行为“。

Swear to god, it's like dealing with an alien civilization. 向上帝发誓,就像处理外星文明一样。


EDIT 3 : In order to avoid confusing future readers - 编辑3 :为了避免混淆未来的读者 -

  • \\` is the emacs regex for "the beginning of the buffer." \\`是用于“缓冲区开头”的emacs正则表达式。 (cf Perl's \\A ) (参见Perl的\\A
  • \\' is the emacs regex for "the end of the buffer." \\'是用于“缓冲区结束”的emacs正则表达式。 (cf Perl's \\Z ) (参见Perl的\\Z
  • ^ is the common-idiom regex for "the beginning of the line." ^是“行首”的常用成语正则表达式。 It can be used in emacs. 它可以在emacs中使用。
  • $ is the common-idiom regex for "the end of the line." $是“行尾”的常用成语正则表达式。 It can be used in emacs. 它可以在emacs中使用。

Because regex searches across multi-line bodies of text are more common in emacs than elsewhere (eg Mx occur ), the backtick and single-quote special characters are used in emacs, and as best as I can tell, they're used in the context of customize-mode because if you are considering generic unknown input to a customize-mode field, it could contain newlines, and therefore you want to use the beginning-of-buffer and end-of-buffer special characters because the beginning and end of the input are not guaranteed to be the beginning and end of a line. 因为正在使用多行文本体系的正则表达式搜索在emacs中比在其他地方更常见(例如Mx occur ),所以在emacs中使用反引号和单引号特殊字符,并且尽我所知,它们被用于自定义模式的上下文,因为如果您正在考虑自定义模式字段的通用未知输入,它可能包含换行符,因此您希望使用缓冲区开头和缓冲区结束特殊字符,因为开始和结束输入的输入不保证是一行的开头和结尾

I am not sure whether to regret hijacking my own Stack Overflow question and essentially turning it into a blog post. 我不确定是否后悔劫持我自己的Stack Overflow问题,并将其转化为博客文章。

In the customize field, you'd enter the regexp according to the syntax described here . 在customize字段中,您将根据此处描述语法输入regexp。 When customize writes the regexp into a string, any backslashes or double-quote chars in the regexp will be escaped, as per regular string escaping conventions. 当custom将regexp写入字符串时,regexp中的任何反斜杠或双引号字符都将按照常规字符串转义约定进行转义。

So in short, just enter single backslashes in the regexp field, and they'll get correctly doubled up in the resulting custom-set-variables clause written to your .emacs . 简而言之,只需在regexp字段中输入单个反斜杠,它们就会在写入.emacs的结果custom-set-variables子句中正确加倍。

Also: since your regexp is for matching filenames, you might try opening up a directory containing files you'd like to match, and then run Mx re-builder RET . 另外:由于regexp用于匹配文件名,因此您可以尝试打开包含您要匹配的文件的目录,然后运行Mx re-builder RET You can then enter the regexp in string-escaped format to confirm that it matches those files. 然后,您可以以字符串转义格式输入正则表达式,以确认它与这些文件匹配。 By typing % m in a dired buffer, you can enter a regexp in unescaped format (ie. just like in the customize field), and dired will mark matching filenames. 通过在dired缓冲区中键入% m ,您可以输入非转义格式的正则表达式(即,就像在自定义字段中一样),并且dired将标记匹配的文件名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM