按照要求,我再次提出了我的问题。
我想将非标题大小写更改为括号内所有单词的标题大小写{}
为了意识到我想匹配括号内的所有单词,但我不知道在[^}]
正则表达式中的位置。
这是我的搜索正则表达式,但它不会选择括号内的单个单词,而是选择括号内的整个文本
/{\s*\zs\(\(\<\w[^}]\+\>\ze\)\s*\)\+}
我的正则表达式有什么问题?
如果正则表达式仅匹配括号内的非标题大小写单词会更好,但这会使其更加复杂。
尝试像这样的法线贴图:
:noremap tc /{<CR>v%:s/\v%V<(\w)(\w*)>%V/\=toupper( submatch(1) ) . tolower( submatch(2) )/g<CR>/}<CR>
它是如何工作的?
/{<CR>
::搜索左大括号。
v%
::视觉选择从当前位置(左大括号)到右一个位置的内容。
:s/.../g<CR>
::替换命令,在视觉选择(%V
)中的标题大小写单词做两组,第一个字母和其余字母。
/}<CR>
::在替换命令之后,如果光标来自不同的行,它的位置被设置在行首,所以为了避免对相同的文本重复映射,在关闭花括号之后设置它的位置,以便在接下来的执行中找到下一个对。
我用以下文字做了一个测试:
Topic One
=========
This is some text about topic one.
It has {multiple paragraphs.} more more mroe
Topic Two
=========
This {is some text about topic} two. It {has only one} paragraph.
并在正常模式下执行tc
命令3 次,它产生:
Topic One
=========
This is some text about topic one.
It has {Multiple Paragraphs.} more more mroe
Topic Two
=========
This {Is Some Text About Topic} two. It {Has Only One} paragraph.
要匹配括号内的单个单词,您不能使用\zs
/\ze
因为新匹配可能仅在前一个结束之后开始,并且\zs
/\ze
在计算匹配的开始/结束时不考虑(它们仅在计算匹配文本时考虑以及放置光标的位置)。您应该改用前瞻和后视:
\%({[^}]*\)\@<=\<\l[^ }]\{-}\>\%([^}]*}\)\@=
. 但是要将非标题大小写更改为标题大小写,有更简单的方法:而不是尝试构建将匹配大括号内的每个单词的正则表达式,分别匹配整个大括号内容并使用嵌套替换:
:s/{\zs.\{-}\ze}/\=substitute(submatch(0), '\<\l', '\U\0', 'g')/g
.