PAYATHON 2026

Sieve 过滤器能否将字符串按空格拆分为字符串列表?

数据小许

Sieve 基础语言和 variables 扩展没有类似常见编程语言中 split() 的操作,无法把字符串转换为可保存在变量中的任意长度列表。示例中的字段固定为六个,可以用 :matches 提取,再逐项写入字符串列表参数。

为什么不能直接生成列表?

问题中的变量保存的是一个字符串:

set "thevariable" "a bb ccc dddd eeeee ffffff";

Sieve 的 string-list 是脚本中的参数语法,例如 ["a", "bb"]。variables 扩展中的 set 接收字符串值,没有提供列表变量或通用的 split() 操作。相关规则见 RFC 5228 的字符串列表定义和 RFC 5229 的 set 定义。

因此,下面的写法仍然只有一个列表元素:

[ "${thevariable}" ]

变量展开只会替换字符串内容,不会把其中的空格、逗号或方括号重新解析成列表结构。即使把列表的文本形式存入变量,结果也一样。

固定六个字段时如何提取?

如果邮件服务支持 variables 扩展,且输入始终是六个非空字段,字段之间恰好有一个普通空格,首尾没有空格,可以这样处理:

require ["variables"];

set "thevariable" "a bb ccc dddd eeeee ffffff";

if string :matches "${thevariable}" "* * * * * *" {
    set "part1" "${1}";
    set "part2" "${2}";
    set "part3" "${3}";
    set "part4" "${4}";
    set "part5" "${5}";
    set "part6" "${6}";
}

匹配成功后,${1} 到 ${6} 分别对应 a、bb、ccc、dddd、eeeee 和 ffffff。其中 * 是 Sieve 通配符,每个通配符对应一个匹配变量,规则见 RFC 5229 第 3.2 节。

接下来,可以在接受 string-list 参数的位置显式写出六个元素:

[ "${part1}", "${part2}", "${part3}",
  "${part4}", "${part5}", "${part6}" ]

元素的值来自变量,但元素数量仍由脚本预先确定。提取结果应在匹配成功的分支中使用,或由后续条件确保本次提取已经成功。

这个替代办法有哪些限制?

  • 模式中的空格只匹配普通空格,不会自动兼容制表符或任意连续空白。
  • * 可以匹配空字符串,也可以包含空格。输入字段过多时,最后一个捕获结果可能包含剩余的多个字段,因此该模式不能严格验证“恰好六个非空字段”。
  • 后续成功的 :matches 测试会更新匹配变量。需要长期使用的结果,应像示例一样立即保存到命名变量。

如果字段数量不固定,仅靠 Sieve 基础语言和 variables 扩展,不能构造并遍历动态列表;基础语言也没有通用循环结构。参见 RFC 5228 的语言设计说明。

邮件服务已禁止 execute :pipe,因此当前无法使用外部程序处理。如果需要任意长度的拆分结果,还需要确认服务商是否提供专用扩展。题目没有给出服务商及其扩展能力,无法据此提供通用命令。

备注:内容仅供参考。