如何在Vim正则表达式中包含一个字面上的@(at符号)?

6

我正在尝试为我正在编写的Vim插件编写语法规则,但是我在编写一个能够匹配以@符号开头和由两个字母后跟任意数量接受字符组成的标识符的Vim正则表达式时遇到了困难。以下是我目前的代码:

syntax match aldaAtMarker "\v@[a-zA-Z]{2,}[\w[:digit:]\-+'()]*"

我知道@后面的所有内容(至少据我所知)都有效,因为我是从一个名为aldaIdentifier的规则中复制粘贴而来的,该规则似乎能正常工作。但是,我在插入前缀文字@符号时遇到了麻烦,因为Vim正则表达式系统显然赋予@特殊含义(请参见:help syntax并查找@)。
按照我上述的语法规则,尝试加载插件会导致以下错误:
Error detected while processing /home/dave/.vim/bundle/vim-alda/syntax/alda.vim:
line   21:
E866: (NFA regexp) Misplaced @
Press ENTER or type command to continue
Error detected while processing /home/dave/.vim/bundle/vim-alda/syntax/alda.vim:
line   21:
E64: @ follows nothing
Press ENTER or type command to continue
Error detected while processing /home/dave/.vim/bundle/vim-alda/syntax/alda.vim:
line   21:
E475: Invalid argument: aldaAtMarker "\v@[a-zA-Z]{2,}[\w[:digit:]\-+'()]*"
Press ENTER or type command to continue

如果我使用\@替换@,就不会出现错误,但是错误的地方被突出显示,这让我想到我的正则表达式中的\@被特殊解释了,而不是被视为字面意义上的@字符。
显然我漏掉了什么,我的谷歌搜索也失败了。在"very magic"(\v)模式下,如何在Vim正则表达式中包含一个字面上的@符号?

1
你尝试过不使用非常魔法模式吗? - Nahuel Fouilleul
虽然 @Nahuel Fouilleul 确定了如何处理这种情况(魔术设置),但你可以使用 Unicode 匹配,\vu0040。 - Patrick Bacon
1
/@/\v\@之间不应该有任何区别。当你说“如果我用@替换@,就没有错误,但是会高亮显示错误的地方”,那么具体是哪些错误呢? - sidyll
我看到的不是像 @voiceIn 这样的东西被突出显示,而是像 aa+a+2 这样的东西被突出显示。 - Dave Yarwood
实际上,除了 @voiceIn 被突出显示之外,我还看到其他东西也被突出显示了。 - Dave Yarwood
我弄清楚了——基本上是我的用户错误。请看我的答案。 - Dave Yarwood
2个回答

4

来自这里

推荐使用默认设置的\m魔法。

否则,使用字符集[@]可以始终匹配@字面值。

3. 魔法                            */magic*
模式中的某些字符被视为字面值。它们与文本中的相同字符匹配。但是,如果在其前面加上反斜杠,则这些字符会获得特殊含义。
其他字符没有反斜杠也具有特殊含义。必须在其前面加上反斜杠才能字面匹配。
一个字符是否被视为字面值取决于“magic”选项和接下来提到的项目。
*/\m* */\M* 使用“\m”使其后的模式被解释为已设置了“magic”,忽略“magic”选项的实际值。 使用“\M”使其后的模式被解释为使用了“nomagic”。
*/\v* */\V* 使用“\v”表示其后的模式中除“0”-“9”、“a”-“z”、“A”-“Z”和“_”之外的所有ASCII字符都具有特殊含义。“very magic”
使用“\V”表示其后的模式中只有反斜杠具有特殊含义。“very nomagic”
示例: after: \v \m \M \V 匹配 'magic' 'nomagic' $ $ $ \$ 匹配行尾 . . \. \. 匹配任何字符 * * \* \* 匹配前面的任意数量的原子 () \(\) \(\) \(\) 将其分组为一个原子 | \| \| \| 分隔替代项 \a \a \a \a 字母字符 \\ \\ \\ \\ 字面反斜杠 \. \. . . 字面点 \{ { { { 字面“{” a a a a 字面“a”
{只有Vim支持\m、\M、\v和\V}
推荐始终将“magic”选项保持默认设置,即“magic”。这样可以避免可移植性问题。要使模式免疫于设置或未设置“magic”选项,请在模式开头放置“\m”或“\M”。

1
没有“推荐”标志。帮助中提到的推荐是保持选项'magic'设置为默认值,以不破坏未使用显式标志的插件。 - sidyll
我同意@sidyll的观点——这似乎建议您在vimrc中设置set magic,以便在插件未使用显式标志(例如其正则表达式模式中的\m)时具有良好的默认值。 - Dave Yarwood
我很感激建议使用\m而不是\v,但在这种情况下,我正在扩展一个现有的正则表达式,该正则表达式使用\v,我不想通过更改模式来潜在地破坏它。事实证明,在\v模式下,\@确实可以工作--请参见我的答案。 - Dave Yarwood
@sidyll,感谢您的帮助,看来我误解了最后一个可移植性问题。 - Nahuel Fouilleul

2

事实证明,我还有另一个语法规则,它以相同的颜色突出显示了一些其他内容,并使我感到困惑。

在非常魔术模式下,\@ 确实能够正确转义 @ 符号:

syntax match aldaAtMarker "\v\@[a-zA-Z]{2,}[\w[:digit:]\-+'()]*"

1
很好你发现了这个问题。魔法模式只会改变转义。如果没有被转义,你需要进行转义,反之亦然。如果不确定,尝试隔离情况并使用正则搜索来帮助测试。 - sidyll

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