我有一个 XML 文件。光是读到这篇文章,我就能看出你很兴奋。
现在其中有一些标签我想完全删除:
<qwerty option=1>
<nmo>sdfsdf</nmo>
<blue>sdfsdf</blue>
</qwerty>
这是一个大文件。如何删除所有标签nmo和blue,包括其内容?在 Emacs 中,或者我的 mac 可以使用的任何其他东西。
Emacs 具有用于导航符号表达式或“sexps”的命令。在 中xml-mode,sexp 导航命令适用于标签。您可以导航到开头<,按C-M-f( forward-sexp) 导航到标签末尾,或按C-M-k( kill-sexp) 终止它。该变量nxml-sexp-element-flag控制是转到开始标记的末尾(默认)还是结束标记的末尾。我更喜欢后者。
要删除这些标签,请首先nxml-sexp-element-flag使用进行设置M-x customize-variable nxml-sexp-element-flag。接下来,搜索您要删除的标签,将点移动到开头<并按C-M-k。将这一切包装在一个宏中,然后重复整个文件,直到搜索失败。
我假设您的 xml 文件格式正确。而且我还认为,与您的示例相反,您的“现实生活”数据比每行一个标签(根标签除外)稍微复杂一些。否则,我们是否同意这就像删除包含给定标签的行一样简单?
这是一个可以实现这一目的的函数的提议:
(defun my-remove-tag (tag)
  (save-excursion
     (let ((case-fold-search nil))
       (while (search-forward-regexp (concat "<" tag "[^\\>]*>"))
     (delete-region
      (match-beginning 0)
      (search-forward (concat "</" tag ">")))))))
调用此函数时,您可能会查找nmo、blue或qwerty标签,如下所示:
(my-remove-tag "nmo")
(my-remove-tag "qwerty")
基本原理是寻找开始标签,然后寻找结束标签,并删除中间的所有内容。标签的属性可能会出现在中间,并且此函数处理包含属性的打开标签。
功能完成后,大小写敏感度将被禁用并恢复。Emacs Point 也用通常的宏恢复:save-excusion。
我把外面的让掉了。不需要手动恢复 case-fold-search 值,let 绑定只是隐藏全局值,它是通过“unshadowing”的方式恢复的。