如何在Racket中对列表元素应用string-replace函数?
解决Racket中
string-replace的两个常见问题 一、批量对列表元素应用string-replace的正确方式
你说得对,apply在这里的问题是它会把列表里的元素追加到函数的参数列表末尾,所以(apply string-replace ";" "" '("a" "b;" "c"))其实等价于调用:
(string-replace ";" "" "a" "b;" "c")
这显然不符合string-replace的参数要求(它需要3个必选参数:原字符串、待替换子串、新内容,再加一个可选的#:all?关键字参数),所以触发了参数数量不匹配的错误。
如果要对列表中的每个元素单独执行string-replace,你需要用map函数来遍历列表,对每个元素应用替换逻辑。示例代码如下:
(map (lambda (s) (string-replace s ";" "")) '("a" "b;" "c"))
这段代码会遍历列表里的每个字符串s,把其中的";"替换为空字符串,最终返回结果'("a" "b" "c"),完全符合你的需求。
二、string-replace返回异常结果的原因及修复
你遇到的第二个问题,核心是搞反了string-replace的参数顺序。在Racket中,string-replace的标准签名是:
(string-replace str old new [#:all? all? #t])
参数顺序是:原字符串 → 要被替换的旧子串 → 替换后的新内容。
你写的(apply string-replace "b" "" '("b;"))等价于直接调用:
(string-replace "b" "" "b;")
这行代码的意思是:把字符串"b"中的所有空串("")替换成"b;"。因为空串在字符串的开头、每个字符之间、结尾都存在,所以替换后会得到奇怪的结果(你看到的"b;bb"就是这种替换的产物)。
如果你想把"b;"中的";"替换成空字符串,正确的调用应该是:
(string-replace "b;" ";" "")
这样就能得到你预期的"b"。如果是要处理列表中的元素,同样可以结合map来批量处理:
(map (lambda (s) (string-replace s ";" "")) '("b;"))
内容的提问来源于stack exchange,提问作者NicolasBourbaki
相关产品推荐
相关产品推荐

