You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MessageFormat中基于多条件实现更优的文本格式化?

优化MessageFormat多参数条件格式化的方案

针对多参数联合判断的格式化需求,仅用MessageFormat(含自定义规则)有几种更简洁的实现方式:

方案1:自定义多条件Format类

把多参数判断逻辑封装成自定义Format,避免嵌套plural的冗长写法。

实现示例:

import java.text.Format
import java.text.ParsePosition
import java.util.*

// 自定义Format,接收多参数条件判断逻辑、匹配成功/失败的文本
class MultiConditionFormat(
    private val condition: (args: Array<Any?>) -> Boolean,
    private val trueText: String,
    private val falseText: String
) : Format() {
    override fun format(obj: Any?, toAppendTo: StringBuffer, pos: FieldPosition): StringBuffer {
        val args = obj as? Array<*> ?: return toAppendTo.append(falseText)
        return toAppendTo.append(if (condition(args as Array<Any?>)) trueText else falseText)
    }

    override fun parseObject(source: String?, pos: ParsePosition?): Any? {
        // 无需解析功能时可空实现
        return null
    }
}

// 使用示例
fun main() {
    val formatStr = "{0}{1,multiCondition}{2}"
    val msgFormat = MessageFormat(formatStr, Locale.ENGLISH)
    
    // 注册自定义格式:判断第0、2位参数是否均非零
    msgFormat.setFormatByArgumentIndex(1, MultiConditionFormat(
        condition = { args -> (args[0] as Int) != 0 && (args[2] as Int) != 0 },
        trueText = " and ",
        falseText = ""
    ))

    // 测试场景
    println(msgFormat.format(arrayOf(1, null, 20))) // 输出:1 and 20
    println(msgFormat.format(arrayOf(0, null, 20))) // 输出:20
    println(msgFormat.format(arrayOf(1, null, 0)))  // 输出:1
    println(msgFormat.format(arrayOf(0, null, 0)))  // 输出:
}

方案2:用复合参数简化逻辑

先把多参数条件转换成单一标记值,再用原生ChoiceFormat匹配结果,写法更简洁。

实现示例:

import java.text.ChoiceFormat
import java.text.MessageFormat
import java.util.*

fun main() {
    // 生成复合标记:0=都为0,1=仅第一个非0,2=仅第二个非0,3=都非0
    fun getCombinedFlag(hour: Int, minute: Int) = when {
        hour == 0 && minute == 0 -> 0
        hour != 0 && minute == 0 -> 1
        hour == 0 && minute != 0 -> 2
        else -> 3
    }

    val formatStr = "{0}{1,choice,0#|1#|2#|3# and }{2}"
    val msgFormat = MessageFormat(formatStr, Locale.ENGLISH)
    
    // 配置ChoiceFormat的匹配规则
    val limits = doubleArrayOf(0.0, 1.0, 2.0, 3.0, 4.0)
    val texts = arrayOf("", "", "", " and ", "")
    msgFormat.setFormatByArgumentIndex(1, ChoiceFormat(limits, texts))

    // 测试场景
    println(msgFormat.format(arrayOf(1, getCombinedFlag(1,20), 20))) // 1 and 20
    println(msgFormat.format(arrayOf(0, getCombinedFlag(0,20), 20))) // 20
}

这个方案无需自定义Format,原生API即可实现,扩展到第三个参数时,只需要新增复合标记的规则即可。

方案3:进阶:扩展MessageFormat模式语法

如果需要频繁使用多参数条件判断,可以自定义MessageFormat.PatternParser,扩展语法支持多参数联合表达式(比如你期望的{plural,0=0&1=0{} other{ and }})。但这种方式需要重写解析逻辑,复杂度较高,适合团队封装通用工具的场景。


内容的提问来源于stack exchange,提问作者Jonny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:26:05