之前有人可能会问这个,但我无法在Google上找到答案...
search
函数查看缓冲区中的整个文件,但只返回匹配的行号。
matchstr
函数可以返回一个令牌,但只查看一个给定的字符串。
如何实现两者结合的功能,并从整个文件中搜索获取令牌?有一个简单的解决方案吗?
答案 0 :(得分:2)
有几种可能性:
您可以使用searchpos()
获取匹配的行号和起始列,然后使用getline()
并通过matchstr()
抓取匹配项,将列作为{start}
参数(正确处理一行中的多个匹配)。
使用searchpos()
两次,第二次使用ceW
参数来结束匹配。现在您有两个位置,您可以为两者设置标记,然后在它们之间拉动文本,或者使用getline()
和strpart()
。
我的ingo-library plugin有一个ingo#text#frompattern#Get( firstLine, lastLine, pattern, replacement, isOnlyFirstMatch, isUnique )
函数可以提取此类匹配。
答案 1 :(得分:2)
在最新版本的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
你可以更加疯狂,恢复光标位置等,但这是基本的想法。
答案 2 :(得分:0)
另一种选择是将文件内容转换为字符串,然后将其作为expr
的{{1}}参数传递:
matchstr()
奖金:如果要使用当前缓冲区而不是任意文件来执行此操作,则可以将对 //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>)
的调用替换为getline(1,'$')
,以获得包含当前缓冲区的所有行的列表。