如何在vim正则表达式中替换或查找非可打印字符?

58

我有一个文件,其中包含一些以^C或^B形式呈现的不可打印字符,我想查找并替换这些字符,我该如何操作?


2
返回翻译文本:/ [^ - ~] 在此处找到答案:https://dev59.com/I37aa4cB1Zd3GeqPucWr#23103760 - Chris Stryczynski
请查看此处:https://superuser.com/a/1400632/510928 - markling
7个回答

91

仅删除控制符:

:%s/[[:cntrl:]]//g

移除非可打印字符(注意,在8.1.1之前的版本中,这也会移除非ASCII字符):

:%s/[^[:print:]]//g

如果你有一些不可打印的、非控制字符,例如零宽度空格,那么它们之间的区别就可以看出来了:

enter image description here


1
至少在 vim 7.3 版本之前,[:print:] 只匹配 ASCII 可打印字符。注意这一点。 - ndemou
@ndemou 这有点棘手,由于 [ ] 包围着 [:print:],^ 应该反转匹配并返回任何不可打印的字符。或者也许那是你的编辑? - dragon788
@dragon788,是的,在我写评论时我就知道它是如何工作的。尝试在ASCII表之外的包含可打印Unicode字符的文本上尝试第二个正则表达式,以理解我的评论(它将删除Unicode字符)。 - ndemou
“然而你为什么认为应该有一个呢?”--好吧,因为正如答案中所述,第一个正则表达式删除控制符号,而第二个则删除不可打印的字符。作为推论,可以说控制符号和不可打印字符之间应该存在一些区别。 - john c. j.
@john-c-j 当然可以,但我想不出一个既不是控制字符又不可打印的字符。也许是我太累了 :-) - ndemou
显示剩余7条评论

49

如果你想将 ^C 替换为 C:

:%s/CtrlVC/C/g

其中 CtrlVC 表示在按住Ctrl键的同时输入V和C。

CtrlV 可以让你输入控制字符。


6
您也可以使用 Ctrl-Q。对于将 Ctrl-V 映射到剪贴板操作的某些用户来说,这非常有用。 - Iain Ballard

15

在 Vim 中保存文件后(假设你正在 Linux 环境中),尝试执行以下操作:

:%!tr -cd '[:print:]\n'

3
@JamesAndino 发送的命令 :% 会使用外部程序 tr 进行筛选,该程序会将所有不是可打印字符 ([:print:]) 或换行符 (\n) 的字符删除 (-d)。 - quasimodo
2
这不是Unicode友好的,因为它是一个POSIX字符类(http://en.wikipedia.org/wiki/Regular_expression#Character_classes)。因此,如果您有包含像“你好”这样的数据的YAML文件,在使用“[:print:]”时,“tr”将剥离Unicode数据。 - atp

10

这里使用 Vim 的控制字符的回答都不起作用,我必须输入一个 Unicode 范围。

:%s/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]//g

这个Unicode范围可以在这篇帖子中找到:https://dev59.com/cnM_5IYBdhLWcg3w43pt#8171868


因为TAB被认为是不可打印的,所以这些“[:cntrl:]”和“[^:print:]”可以匹配TAB(0x9,C-I)。 - mosh

5

您可以使用:

:%s/^C//g

要得到一个 ^C,你需要按住控制键,然后按下 VC(两个都要在按住控制键的同时),然后就会出现 ^C。这将找到所有出现的并将它们替换为空。
要同时删除 ^C^B,可以执行以下操作:
:%s/^C\|^B//g

5

您可以使用CTRL-V前缀输入它们,或者如果它们不容易键入,则使用CTRL-R"来复制并插入它们。


5

其他回答中未提及的一种选择。

删除一个具有长十六进制代码的特定Unicode字符,例如 <200b>

:%s/\%U200b//g

这正是我在寻找的!请参见http://vimdoc.sourceforge.net/htmldoc/pattern.html - David Dyck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接