如何从字符串中删除装饰(文本属性)?


17

所谓的“装饰字符串”,是指

#("foo" 0 4 (fontified t face font-lock-function-name-face))

...与“普通字符串”相对

"foo"

(如果Elisp代码直接从缓冲区读取字符串,则可以这样修饰它。)

将装饰后的字符串转换为普通字符串的最简单方法是什么(通过剥离所有装饰)?


7
substring-no-properties
Dan

为什么需要删除这些属性?他们通常没有伤害。仅假装它们不存在可能是一个很好的解决方案。
YoungFrog

Answers:


15

[您的属性字符串看起来不正确-也许您复制了错误的字符串。 foo只有3个字符,因此无法在0到4字符上进行字体化(即,0、1、2和3字符-这是4个字符)。在此示例中,我使用3而不是4。]

(let* ((foo    #("foo" 0 3 (fontified t face font-lock-function-name-face)))
       (start  0)
       (end    (length foo)))
  (set-text-properties start end nil foo)
  foo)

set-text-properties是的内置函数C source code

(set-text-properties START END PROPERTIES &optional OBJECT)

完全替换从START到的文本属性END

第三个参数PROPERTIES是新的属性列表。

如果可选的第四个参数OBJECT是缓冲区(或nil,表示当前缓冲区),START并且END是缓冲区位置(整数或标记)。If OBJECT是一个字符串,START并且END是从0开始的索引。如果PROPERTIES为nil,则效果是从OBJECT的指定部分删除所有属性。

请参见Elisp手册,节点“ 更改属性”。在那里,您将在函数remove-text-properties(您还可以使用它来完成这项工作)下看到以下内容:

要从某些文本中删除所有文本属性,请使用set-text-properties并指定nil新的属性列表。


正如@Dan所提到的,您也可以使用substring-no-properties,但要注意它会返回一个新字符串。它不会修改您传递的实际字符串对象。两者remove-text-propertiesset-text-properties更改您传递它们的字符串。

例如:

(setq foo #("foo" 0 3 (fontified t face font-lock-function-name-face)))
(setq bar foo)
(set-text-properties 0 (length foo) nil foo)

无论foobar现在正好"foo",没有属性。

但:

(setq foo #("foo" 0 3 (fontified t face font-lock-function-name-face)))
(setq bar foo)
(setq foo (substring-no-properties foo))

现在foo没有属性,但bar仍然有它们。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.