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

如何编写基于Lens的函数递增字符串数字后缀(无则保持原串)

基于Lens实现字符串数字后缀递增函数

需求说明

需要实现一个函数,遵循以下规则处理字符串:

  • 若字符串末尾带有连续数字后缀,将该数字值加1
  • 无数字后缀、数字不在末尾时,保持原字符串不变

示例效果:

"aaa1" -> "aaa2"
"aaa_123" -> "aaa_124"
"" -> ""
"aaa" -> "aaa"
"123a" -> "123a"
"3a5" -> "3a6"

解决方案

你提到的lens库中suffixed只能匹配固定后缀,无法处理动态的数字序列,因此需要自定义Prism/Traversal来实现需求。下面给出两种基于Lens风格的实现方式:


方式一:自定义Traversal实现

首先导入必要的模块:

import Control.Lens
import Data.Text (Text)
import qualified Data.Text as T
import Data.Char (isDigit)

先实现字符串拆分逻辑,将字符串拆分为前缀和末尾的数字(如果存在):

splitEndDigits :: Text -> (Text, Maybe Integer)
splitEndDigits t = case T.spanEnd isDigit t of
  ("", prefix) -> (prefix, Nothing)
  (digitStr, prefix) -> case reads (T.unpack digitStr) of
    [(n, "")] -> (prefix, Just n)
    _ -> (t, Nothing)

基于拆分逻辑定义Traversal,用于聚焦并修改末尾数字:

traverseEndingDigit :: Traversal' Text Integer
traverseEndingDigit f t = case splitEndDigits t of
  (prefix, Just n) -> (\newN -> prefix <> T.pack (show newN)) <$> f n
  (prefix, Nothing) -> pure prefix

最后用over函数结合Traversal实现递增:

incrementEndingDigit :: Text -> Text
incrementEndingDigit = over traverseEndingDigit (+1)

方式二:自定义Prism实现

如果更倾向于用Prism,可以定义一个匹配「前缀+末尾数字」的Prism:

_EndingDigitPair :: Prism' Text (Text, Integer)
_EndingDigitPair = prism' embed match
  where
    embed (prefix, n) = prefix <> T.pack (show n)
    match t = case splitEndDigits t of
      (prefix, Just n) -> Just (prefix, n)
      _ -> Nothing

通过组合Prism和_2 Lens聚焦到数字部分,实现递增:

incrementEndingDigit :: Text -> Text
incrementEndingDigit = over (_EndingDigitPair . _2) (+1)

测试验证

两种方式都能满足示例中的所有场景,比如:

incrementEndingDigit "aaa1"       -- 返回 "aaa2"
incrementEndingDigit "aaa_123"    -- 返回 "aaa_124"
incrementEndingDigit ""           -- 返回 ""
incrementEndingDigit "aaa"        -- 返回 "aaa"
incrementEndingDigit "123a"       -- 返回 "123a"
incrementEndingDigit "3a5"        -- 返回 "3a6"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:15:28