如果我正确理解了您的问题,您想要计算一行中非空格字符的数量。一个相当简单的方法是删除空格并查看结果行的长度。因此,可以使用以下代码:
function! Countchars()
let l = 1
let char_count = 0
while l <= line("$")
let char_count += len(substitute(getline(l), '\s', '', 'g'))
let l += 1
endwhile
return char_count
endfunction
回答这个问题的关键部分是使用替换功能。命令如下:
substitute(expr,pattern,repl,flags)
在这种情况下,
expr
是
getline(l)
,其中
l
是正在迭代的行数。
getline()
返回该行的内容,因此这就是正在解析的内容。模式是正则表达式
\s
,它匹配任何单个空格字符。它被替换为
''
,即一个空字符串。标志
g
使其重复替换与该行上找到的空格数量相同的次数。
替换完成后,
len()
给出非空白字符的数量,然后再使用
+=
加上当前
char_count
的值。
我从您的示例中更改了一些内容:
- 函数名称以大写字母开头(这是用户定义函数的要求:请参见
:help user-functions
)
- 我将
count
重命名为char_count
,因为您不能使用与函数相同的变量名称,count()
是内置函数
- 同样适用于
line
:我将其重命名为l
- 文件中的第一行是第1行,而不是第0行,因此我将
l
初始化为1
- while循环计算到但不包括最后一行,我假设您想要文件中的所有行(这可能与行编号从1开始有关):我将您的代码更改为使用
<=
而不是<
- Vim中的块不基于缩进,因此
while
需要一个endwhile
- 在您的函数中,您有
let line = getline('。')
- 我在
function
定义上添加了一个!
,因为它使增量开发变得更加容易(每次重新源代码文件时,它都会用新版本覆盖该函数,而不是输出关于已存在的错误消息)。
- 通过文件进行递增的方式略有不同...
在您的函数中,您使用了
let line = getline('.')
。忽略变量名,这个实现仍然存在一些问题。我认为您想表达的是
let l = line('.')
,它给出当前行的行号。
getline('.')
会给出当前行的内容,因此while行上的比较将当前行的内容与最后一行的数字进行比较,这将失败。另一个问题是,您实际上没有在文件中移动,所以当前行将是您调用函数时所在的任何行,并且永远不会改变,导致无限循环。我已经用简单的
+= 1
替换了它以遍历整个文件。
当前行有一些有用的方法可以完成此操作,例如,如果您编写一个接受一系列行的函数,但我认为我已经写了足够的内容,以上内容应该能够让您开始。无论如何,stackoverflow上有很多人可以帮助解决任何问题!
请参考:
:help usr_41.txt
:help function-list
:help user-functions
:help substitute()
随着:help
命令的使用,我在函数中使用了各种东西(例如getline()
、line()
、let+=
等)。
希望这有所帮助。
len('ñ')
会返回2,为了处理多字节字符,请使用len(split(getline(l),'\zs\s*'))
。 - Raimondi