Next: 具有特殊含义的文本属性, Previous: 修改文本属性, Up: 文本属性   [Contents][Index]


33.19.3 文本属性搜索函数 ¶

在文本属性的典型使用场景中,通常有多个连续字符的某一属性值相同。 相比逐字符检查,处理属性值相同的文本块效率会高得多。

以下函数可实现该需求,它们使用 eq 比较属性值。 所有函数中,参数 object 均默认指向当前缓冲区。

为保证性能,务必为这些函数指定 limit 参数,尤其是搜索单个属性的函数— 否则,若目标属性未发生变化,函数可能会花费大量时间扫描至缓冲区末尾。

这些函数不会移动光标(point),而是返回一个位置(或 nil)。 需注意,位置始终位于两个字符之间;这些函数返回的位置,恰好是两个属性不同字符的分界处。

Function: next-property-change pos &optional object limit ¶

该函数从字符串或缓冲区 object 的 pos 位置向前扫描文本, 直至发现某文本属性发生变化,然后返回该变化的位置。 换言之,它返回 pos 之后首个属性与 pos 紧邻字符属性不同的字符位置。

若 limit 非 nil,扫描会在 limit 位置终止。 若该位置前未发现属性变化,函数返回 limit。

若 limit 为 nil 且属性一直无变化直至 object 末尾,返回值为 nil。 若返回值非 nil,则为大于或等于 pos 的位置;仅当 limit 等于 pos 时,返回值才等于 pos。

以下示例演示如何按属性恒定的文本块扫描缓冲区:

(while (not (eobp))
  (let ((plist (text-properties-at (point)))
        (next-change
         (or (next-property-change (point) (current-buffer))
             (point-max))))
    Process text from point to next-change...
    (goto-char next-change)))
Function: previous-property-change pos &optional object limit ¶

该函数与 next-property-change 类似,但从 pos 位置向后(反向)扫描。 若返回值非 nil,则为小于或等于 pos 的位置;仅当 limit 等于 pos 时,返回值才等于 pos。

Function: next-single-property-change pos prop &optional object limit ¶

该函数扫描文本以查找 prop 属性的变化,然后返回该变化的位置。 扫描从字符串或缓冲区 object 的 pos 位置向前进行。 换言之,该函数返回 pos 之后首个 prop 属性与 pos 紧邻字符属性不同的字符位置。

若 limit 非 nil,扫描会在 limit 位置终止。 若该位置前未发现属性变化,next-single-property-change 返回 limit。

若 limit 为 nil 且属性一直无变化直至 object 末尾,返回值为 nil。 若返回值非 nil,则为大于或等于 pos 的位置;仅当 limit 等于 pos 时,返回值才等于 pos。

Function: previous-single-property-change pos prop &optional object limit ¶

该函数与 next-single-property-change 类似,但从 pos 位置向后(反向)扫描。 若返回值非 nil,则为小于或等于 pos 的位置;仅当 limit 等于 pos 时,返回值才等于 pos。

Function: next-char-property-change pos &optional limit ¶

该函数与 next-property-change 类似,但同时考虑覆盖层属性和文本属性; 若缓冲区末尾前未发现变化,返回缓冲区最大位置而非 nil(从这个角度看,它更接近对应的覆盖层函数 next-overlay-change,而非 next-property-change)。 该函数无 object 参数,因为它仅作用于当前缓冲区。 它返回下一个任一类型属性发生变化的位置。

Function: previous-char-property-change pos &optional limit ¶

该函数与 next-char-property-change 类似,但从 pos 位置向后(反向)扫描; 若未发现变化,返回缓冲区最小位置。

Function: next-single-char-property-change pos prop &optional object limit ¶

该函数与 next-single-property-change 类似,但同时考虑覆盖层属性和文本属性; 若 object 末尾前未发现变化,返回 object 中的最大有效位置而非 nil。 与 next-char-property-change 不同,该函数 包含 object 参数; 若 object 非缓冲区,则仅考虑文本属性。

Function: previous-single-char-property-change pos prop &optional object limit ¶

该函数与 next-single-char-property-change 类似,但从 pos 位置向后(反向)扫描; 若未发现变化,返回 object 中的最小有效位置。

Function: text-property-any start end prop value &optional object ¶

若 start 至 end 范围内至少有一个字符的 prop 属性值为 value, 该函数返回非 nil 值——更准确地说,返回首个符合条件字符的位置;否则返回 nil。

可选的第五个参数 object 指定要扫描的字符串或缓冲区,位置均相对于 object。 object 的默认值为当前缓冲区。

Function: text-property-not-all start end prop value &optional object ¶

若 start 至 end 范围内至少有一个字符的 prop 属性值不等于 value, 该函数返回非 nil 值——更准确地说,返回首个符合条件字符的位置;否则返回 nil。

可选的第五个参数 object 指定要扫描的字符串或缓冲区,位置均相对于 object。 object 的默认值为当前缓冲区。

Function: text-property-search-forward prop &optional value predicate not-current ¶

根据 predicate 规则,搜索下一个 prop 属性匹配 value(默认值为 nil)的文本区域。

该函数模仿 search-forward(see 字符串搜索)及其相关函数的行为: 它会移动光标,但返回一个描述匹配结果的结构体,而非通过 match-beginning 等函数返回结果。

若未找到属性值匹配的文本,函数返回 nil;若找到,光标会移至该匹配文本属性区域的末尾, 函数返回一个包含匹配信息的 prop-match 结构体。

predicate 可以是 t(等同于 equal)、nil(表示“不相等”), 或一个接收两个参数的谓词函数:value 和候选匹配缓冲区位置的 prop 文本属性值。 若匹配成功,该函数应返回非 nil;否则返回 nil。

若 not-current 非 nil,且光标已处于属性匹配区域内,则跳过该区域,查找下一个匹配区域。

prop-match 结构体有以下访问函数: prop-match-beginning(匹配起始位置)、 prop-match-end(匹配结束位置)、 prop-match-value(匹配起始位置的 property 属性值)。

以下示例使用一个内容如下的缓冲区:

This is a bold and here’s bolditalic and this is the end.

即 “bold” 相关单词应用了 bold 外观样式,“italic” 单词应用了 italic 外观样式。

光标位于起始位置时:

(while (setq match (text-property-search-forward 'face 'bold t))
  (push (buffer-substring (prop-match-beginning match)
                          (prop-match-end match))
        words))

这段代码会提取所有应用 bold 外观样式的单词。

(while (setq match (text-property-search-forward 'face nil t))
  (push (buffer-substring (prop-match-beginning match)
                          (prop-match-end match))
        words))

这段代码会提取所有无外观样式属性的文本片段,结果为列表 ‘("This is a " "and here's " "and this is the end")’ (由于使用了 push,实际顺序为逆序,详见 see 修改列表变量)。

(while (setq match (text-property-search-forward 'face nil nil))
  (push (buffer-substring (prop-match-beginning match)
                          (prop-match-end match))
        words))

这段代码会提取所有 face 属性被设置的区域,且会按属性变化位置拆分, 因此结果为 ‘("bold" "bold" "italic")’。

以下是更贴近实际的使用场景:假设缓冲区中某些段落代表 URL,且被标记了 shr-url 属性。

(while (setq match (text-property-search-forward 'shr-url nil nil))
  (push (prop-match-value match) urls))

这段代码会提取所有此类 URL 组成的列表。

Function: text-property-search-backward prop &optional value predicate not-current ¶

该函数与 text-property-search-forward 类似,但方向为向后搜索; 若找到匹配项,光标会移至匹配区域的起始位置(而非末尾)。


Next: 具有特殊含义的文本属性, Previous: 修改文本属性, Up: 文本属性   [Contents][Index]