删除emacs中某种类型的所有标签

can*_*boy 6 regex xml emacs

我有一个 XML 文件。光是读到这篇文章,我就能看出你很兴奋。

现在其中有一些标签我想完全删除:

<qwerty option=1>
<nmo>sdfsdf</nmo>
<blue>sdfsdf</blue>
</qwerty>
Run Code Online (Sandbox Code Playgroud)

这是一个大文件。如何删除所有标签nmoblue,包括其内容?在 Emacs 中,或者我的 mac 可以使用的任何其他东西。

ata*_*lor 5

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。将这一切包装在一个宏中,然后重复整个文件,直到搜索失败。


yve*_*mes 3

我假设您的 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 ">")))))))
Run Code Online (Sandbox Code Playgroud)

调用此函数时,您可能会查找nmoblueqwerty标签,如下所示:

(my-remove-tag "nmo")
(my-remove-tag "qwerty")
Run Code Online (Sandbox Code Playgroud)

基本原理是寻找开始标签,然后寻找结束标签,并删除中间的所有内容。标签的属性可能会出现在中间,并且此函数处理包含属性的打开标签。

功能完成后,大小写敏感度将被禁用并恢复。Emacs Point 也用通常的宏恢复:save-excusion

更新

我把外面的让掉了。不需要手动恢复 case-fold-search 值,let 绑定只是隐藏全局值,它是通过“unshadowing”的方式恢复的。