如何匹配单词中的特定字母

How to match specific letters in words

我目前正在学习俄语,西里尔字母的编码有一个警告:有些看起来与 ASCII 完全一样。例子。 »облако«(云)这个词既不包含 »a« 也不包含 »o«,而是包含 »а« 和 »о«。如果您还没有得到它,请尝试启动浏览器搜索对话框,输入 »a« 或 »o«,使用一些突出显示所有功能,您将看到 »а« 和 »о« 两者保持黑暗。

所以,现在我想在 vim 中强调这个问题。因为我使用的是混合语言文本文件,所以我不能只突出显示每个 ASCII 字母(这很容易),相反,我希望所有包含至少一个西里尔字母的单词中的所有 ASCII 字母都被错误突出显示。我目前的方法是使用这个匹配项:

" Here, I use бакло as a shortcut for the list of all cyrillic letters,
" this makes this a small self contained example for the word used in the
" problem desctiption, without having the full list in all lines.
" To get the file I actually have, run
" :%s/бакло/ЖжФфЭэЗзЧчБбАаДдВЬвьЪъЫыСсЕеёНнЮюІіКкМмИиЙйПпЛлОоРрЯяГгТтЦцШшЩщХхУу/g
syn match russianWordOk "[бакло]\+"

syn match russianWordError "[бакло][a-zA-Z0-9_]\+"hs=s+1
syn match russianWordError "[a-zA-Z0-9_]\+[бакло]"he=e-1
syn match russianWordError "[бакло][a-zA-Z0-9_]\+[бакло]"hs=s+1,he=e-1

但是,就像 »облaко«(现在 a 是 ASCII)一样,突出显示仍会将 »обл« 标记为有效,将 »a« 标记为无效,将 »к« 标记为不是关键字的一部分(它是关键字的一部分匹配的 russianWordError 关键字),最后剩余的 »о« 再次有效。相反,我想要的是让整个单词成为匹配的 russianWordError 关键字的一部分,但仍然只有 »a« 被突出显示为非法。有没有办法,如果有,我该如何实现?

为了仅匹配 整个单词 ,而不匹配其他单词中的片段,请将您的模式包装在 \<\> 中。然后这些断言将基于 Vim 的 'iskeyword' 设置,应该没问题。 (或者,您可以通过 \@<=\@= 进行其他后视和先行断言。)

syn match russianWordOk "\<[бакло]\+\>"

我不会通过 hs= / he= 而是通过包含的组来突出显示错误的 ASCII 字符。首先,识别不良混合词。开头或结尾必须至少有一个西里尔字母。其余的至少是一个(即用 \+ 重复 \%(...\) 组,否则你只会匹配单个错误词)ASCII,中间可能有其他西里尔字母:

syn match russianWordBad "\<\%([бакло]*[a-zA-Z0-9_]\)\+[бакло]\+\>" contains=russianWordError
syn match russianWordBad "\<[бакло]\+\%([a-zA-Z0-9_][бакло]*\)\+\>" contains=russianWordError

这包含执行错误突出显示的 ASCII 语法组。因为 contained,它只匹配另一个组(这里:russianWordBad)。

syn match russianWordError "[a-zA-Z0-9_]" contained