在Emacs中突出显示并替换不可打印的unicode字符

时间:2011-09-26 19:23:13

标签: unicode emacs

我有一个UTF-8文件,其中包含一些Unicode字符,例如LEFT-TO-RIGHT OVERRIDE(U + 202D),我想从文件中删除它们。在Emacs中,它们是隐藏的(应该是正确的行为?)。如何使这种“异国情调”的unicode字符可见(同时不改变“常规”unicode字符的显示,如德语变音符号)?如何在之后替换它们(例如replace-stringC-X 8 Ret不适用于isearch / replace-string)。

在Vim中,它非常简单:这些字符默认显示为十六进制表示(这是一个错误或缺少的功能吗?),您可以使用:%s/\%u202d//g轻松删除它们。这应该可以用Emacs吗?

3 个答案:

答案 0 :(得分:9)

你可以M-x find-file-literally然后你会看到这些字符。

然后您可以使用常规string-replace

删除它们

答案 1 :(得分:4)

这个怎么样:

键入 M - : (kill-new "\u202d"),将要匹配的U + 202d字符放在kill ring的顶部。然后你可以将该字符串拉入各种搜索命令,使用 Cy (例如query-replace)或 My (例如isearch-forward)。

(已编辑添加:)

您也可以非交互式地调用命令,这与交互式调用没有相同的键盘输入困难。例如,键入 M - :然后:

(replace-string "\u202d" "")

这有点类似于你的Vim版本。一个区别是它只执行从光标位置到文件底部(或缩小区域)的替换,因此您需要在运行命令之前转到文件的顶部(或缩小区域)以替换所有匹配。

答案 2 :(得分:0)

我也有这个问题,这对于提交尤其令人讨厌,因为在发现错误时修复日志消息可能为时已晚。因此,我修改了键入C-x C-c时使用的功能,以检查是否存在不可打印的字符,即匹配"[^\n[:print:]]",如果有,则将光标放在其上,然后输出消息,并且不要杀死缓冲区。然后可以根据上下文手动删除该字符,将其替换为可打印的字符,或其他。

用于检测(并将光标定位在不可打印的字符之后)的代码是:

(progn
  (goto-char (point-min))
  (re-search-forward "[^\n[:print:]]" nil t))

注意:

  • 无需保存当前光标位置,因为在这里,缓冲区将被杀死,或者光标将被故意放置在不可打印的字符上。
  • 您可能需要略微修改正则表达式。例如,制表符是不可打印的字符,我认为是这样,但是您可能还想接受它。
  • 关于regexp中的[:print:]字符类,您依赖于C库。某些可打印字符可能会被视为不可打印,例如一些最近的表情符号(但并非所有人都在乎)。
  • 当且仅当存在不可打印的字符时,re-search-forward返回值才被视为true。这正是我们想要的。

这是我用于Subversion提交的代码段(这是在我的.emacs中更复杂的代码之间)。

(defvar my-svn-commit-frx "/svn-commit\\.\\([0-9]+\\.\\)?tmp\\'")

    ((and (buffer-file-name)
          (string-match my-svn-commit-frx (buffer-file-name))
          (progn
            (goto-char (point-min))
            (re-search-forward "[^\n[:print:]]" nil t)))
     (backward-char)
     (message "The buffer contains a non-printable character."))

cond中,即我仅将此规则应用于Subversion提交所使用的文件名。可以使用(backward-char),这取决于您希望光标移到不可打印字符的上方还是紧随其后。