如何从 vimscript 中的整个文件中搜索令牌?
How can I get a token from a search in a whole file in vimscript?
之前可能有人问过这个问题,但我在 google...
上找不到答案
search
函数查看缓冲区中的整个文件,但只有return匹配的行号。
matchstr
函数可以 return 一个标记,但只查看一个给定的字符串。
如何实现结合两者的功能,在整个文件中搜索得到token?有没有简单的解决办法?
有几种可能:
选项A
您可以使用 searchpos()
获取匹配项的行号和起始列,然后使用 getline()
并通过 matchstr()
获取匹配项,使用列作为 {start}
参数(以正确处理一行中的多个匹配项)。
选项 B
两次使用searchpos()
,第二次使用ceW
参数得到匹配结束。现在您有两个位置,您可以为两个位置都设置标记,然后在它们之间拉出文本,或者使用 getline()
和 strpart()
.
选项 C
我的 ingo-library plugin 有一个 ingo#text#frompattern#Get( firstLine, lastLine, pattern, replacement, isOnlyFirstMatch, isUnique )
函数可以提取这样的匹配项。
在 Vim 的最新版本(7.3.610 及更高版本)中,您可以(ab)使用 Vim 的正常模式搜索对象 "gn" 来执行此操作。
首先,将"last search"寄存器设置为你想要的模式:
let @/='my pattern'
接下来,转到文件的开头,然后拉出下一个搜索结果:
normal! ggygn
现在,搜索文本在寄存器中 @0
如果你想使用不同的寄存器,你也可以这样做:
normal! gg"aygn
现在在注册中@a
注意,所有这些都会破坏搜索和其他寄存器,因此保存和恢复这些寄存器是有礼貌的。类似于:
function MyGetSearch(pattern)
let oldpat=@/
let @/=a:pattern
let old_a=@a
normal! gg"aygn
let result=@a
let @a=old_a
let @/=oldpat
return result
endfun
你可以更疯狂地使用这个,恢复光标位置等等,但这是基本的想法。
另一种选择是将文件的内容转换为字符串,然后将其作为 matchstr()
的 expr
参数传递:
//get a list containing all lines in the file as items:
let lineList = readfile(<filename>)
//join the lines into a single string using "\n" or your preferred line delimiter:
let fileString = join(lineList, "\n")
//search fileString for your pattern:
let matchedText = matchstr(fileString, <pattern to match>)
奖励:如果您想使用当前缓冲区而不是任意文件执行此操作,您可以将对 readfile()
的调用替换为 getline(1,'$')
以获取包含当前缓冲区所有行的列表缓冲区。
之前可能有人问过这个问题,但我在 google...
上找不到答案search
函数查看缓冲区中的整个文件,但只有return匹配的行号。matchstr
函数可以 return 一个标记,但只查看一个给定的字符串。
如何实现结合两者的功能,在整个文件中搜索得到token?有没有简单的解决办法?
有几种可能:
选项A
您可以使用 searchpos()
获取匹配项的行号和起始列,然后使用 getline()
并通过 matchstr()
获取匹配项,使用列作为 {start}
参数(以正确处理一行中的多个匹配项)。
选项 B
两次使用searchpos()
,第二次使用ceW
参数得到匹配结束。现在您有两个位置,您可以为两个位置都设置标记,然后在它们之间拉出文本,或者使用 getline()
和 strpart()
.
选项 C
我的 ingo-library plugin 有一个 ingo#text#frompattern#Get( firstLine, lastLine, pattern, replacement, isOnlyFirstMatch, isUnique )
函数可以提取这样的匹配项。
在 Vim 的最新版本(7.3.610 及更高版本)中,您可以(ab)使用 Vim 的正常模式搜索对象 "gn" 来执行此操作。
首先,将"last search"寄存器设置为你想要的模式:
let @/='my pattern'
接下来,转到文件的开头,然后拉出下一个搜索结果:
normal! ggygn
现在,搜索文本在寄存器中 @0
如果你想使用不同的寄存器,你也可以这样做:
normal! gg"aygn
现在在注册中@a
注意,所有这些都会破坏搜索和其他寄存器,因此保存和恢复这些寄存器是有礼貌的。类似于:
function MyGetSearch(pattern)
let oldpat=@/
let @/=a:pattern
let old_a=@a
normal! gg"aygn
let result=@a
let @a=old_a
let @/=oldpat
return result
endfun
你可以更疯狂地使用这个,恢复光标位置等等,但这是基本的想法。
另一种选择是将文件的内容转换为字符串,然后将其作为 matchstr()
的 expr
参数传递:
//get a list containing all lines in the file as items:
let lineList = readfile(<filename>)
//join the lines into a single string using "\n" or your preferred line delimiter:
let fileString = join(lineList, "\n")
//search fileString for your pattern:
let matchedText = matchstr(fileString, <pattern to match>)
奖励:如果您想使用当前缓冲区而不是任意文件执行此操作,您可以将对 readfile()
的调用替换为 getline(1,'$')
以获取包含当前缓冲区所有行的列表缓冲区。