如何从vimscript中的整个文件中的搜索中获取令牌?

时间:2015-01-01 16:22:12

标签: regex vim

之前有人可能会问这个,但我无法在Google上找到答案...

  1. search函数查看缓冲区中的整个文件,但只返回匹配的行号。

  2. matchstr函数可以返回一个令牌,但只查看一个给定的字符串。

  3. 如何实现两者结合的功能,并从整个文件中搜索获取令牌?有一个简单的解决方案吗?

3 个答案:

答案 0 :(得分:2)

有几种可能性:

选项A

您可以使用searchpos()获取匹配的行号和起始列,然后使用getline()并通过matchstr()抓取匹配项,将列作为{start}参数(正确处理一行中的多个匹配)。

选项B

使用searchpos()两次,第二次使用ceW参数来结束匹配。现在您有两个位置,您可以为两者设置标记,然后在它们之间拉动文本,或者使用getline()strpart()

选项C

我的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()

readfile() join() 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,'$'),以获得包含当前缓冲区的所有行的列表。