有时我会使用string()
函数来生成可分析的字符串。
例如,:echo string("hello world")
显示:
'hello world'
但是,如果我将真实的回车符添加到字符串中,结果将变得无法分析,这仅仅是因为 回车不进行转换。
例如,:echo string("hello\nworld")
显示:
'hello
world'
我原本期望:
"hello\nworld"
是否可以在不编写专用函数的情况下获得 any 字符串的可解析版本?
编辑
更准确地说,我需要与:execute
命令一起使用“可分析”的字符串,以便创建可自定义的映射。基本思想是即使在a:toinsert
参数中有一些CR,也能够使用以下代码:
function! InsertMapping(lhs, toinsert)
let l:rhs = printf('<c-r>=%s<cr>', string(a:toinsert))
exe 'inoremap' a:lhs l:rhs
endf
" This call is working:
call InsertMapping('<c-r><c-e>', "hello world")
" This one throws an error:
call InsertMapping('<c-r><c-e>', "hello\nworld")
" E492: Not an editor command: world')<cr>
实际上,对InsertMapping()
的最后一次调用将尝试执行:
inoremap <c-r><c-e> <c-r>='hello
world'<cr>
当然,我需要执行:
inoremap <c-r><c-e> <c-r>="hello\nworld"<cr>
请注意,我需要保留<c-r>=
,因为我的实际用例更加复杂,并且需要一些函数调用;因此无法像这样简化映射:
inoremap <c-r><c-e> hello<cr>world
答案 0 :(得分:0)
不知道您究竟是什么意思“可分析”。如果您想使用eval()
来获取原始字符串值,则可以使用它。您会看到真正的换行符是由于echo()
函数而被打印出来的,它将\n
扩展为一个换行符。
尝试一下:
let a="hi\nworld"
echo a==eval(string(a))
echo a==eval(string("hi\nworld"))
两者都将返回1
(true)。因此它是“可分析的”。
如果我不理解您的“可分析”的含义,请举一些例子。
答案 1 :(得分:0)
我终于写了一个专用的函数来对vim字符串进行字符串化;它远非完美,但它将为所有测试案例提供“正确”的输出。如果在字符串中根本没有什么特别的地方,它会返回单引号的字符串,这在某些极少数情况下可能会稍微提高性能。
代码如下:
let s:specials = {
\ "\b":'\b', "\e":'\e', "\f":'\f', "\n":'\n',
\ "\r":'\r', "\t":'\t', "\\":'\\', "\"":'\"',
\}
function! Stringify(source)
let output = ''
let string_is_special = v:false
for i in range(strlen(a:source))
let char = a:source[i]
let ascii = char2nr(char)
let char_is_special = v:false
for [key, str] in items(s:specials)
if char == key
let output .= str
let char_is_special = v:true
let string_is_special = v:true
break
endif
endfor
if !char_is_special
if ascii < 32
let output .= printf('\x%02x', ascii)
let string_is_special = v:true
else
let output .= char
endif
endif
endfor
return printf(string_is_special ? '"%s"' : "'%s'", output)
endf
以下是一些快速测试:
let tests = [
\ "simple string",
\ 'back \ slash',
\ "carriage \n return",
\ "utf8 frénçh àccènts",
\ "\x47\x6e\x75",
\ "ctrl-w special key: \<c-w>",
\ ]
for s in tests
echo Stringify(s)
endfor
这是测试输出:
'simple string'
"back \\ slash"
"carriage \n return"
'utf8 frénçh àccènts'
'Gnu'
"ctrl-w special key: \x17"
答案 2 :(得分:-1)
在Vim中,单引号和双引号的行为不同。
在双引号之间,会解释特殊字符,例如\n
,因此:
"hello\nworld"
成为:
hello
world
,您必须将\
加倍才能实际获得\n
:
"hello\\nworld"
在单引号之间,不解释特殊字符,因此:
'hello\nworld'
成为:
hello\nworld
所有这些都在:help expr-"
和:help expr-'
下进行了解释。