如何在Elixir中用模式匹配判断列表项是否以变量指定字符串开头
Elixir中用变量匹配指定前缀的字符串元素
你遇到的错误是因为Elixir的模式匹配规则:<>操作符左侧必须是字面量二进制,编译器需要在编译时确定它的大小,变量的大小无法提前验证,所以直接用变量放在<>左边会报错。
下面给你两种实用的解决方案:
方案一:用标准库函数String.starts_with?/2判断(推荐)
放弃在模式匹配里硬写前缀,转而在函数体内用标准库函数判断每个元素是否符合条件,这种方式简单直观,支持任意变量前缀:
defmodule StringStartsWith do # 空列表直接返回空 def search([], _prefix), do: [] # 处理非空列表 def search([item | tail], prefix) do if String.starts_with?(item, prefix) do # 符合条件就保留当前元素,继续递归 [item | search(tail, prefix)] else # 不符合就跳过,继续递归 search(tail, prefix) end end end # 调用示例 StringStartsWith.search(["CaseDown", "YoHua", "CaseUp"], "Case") |> IO.inspect()
运行结果会输出 ["CaseDown", "CaseUp"],完全符合需求。
方案二:用二进制大小绑定实现模式匹配
如果一定要用模式匹配,可以通过绑定前缀的字节长度来构造合法的匹配模式,让编译器能确定匹配的字节数:
defmodule StringStartsWith do def search([], _prefix), do: [] # 用binary-size(size)指定匹配的字节数,size由前缀的byte_size动态绑定 def search([<<prefix::binary-size(size), rest::binary>> | tail], prefix) when size = byte_size(prefix) do [<<prefix::binary, rest::binary>> | search(tail, prefix)] end # 不符合条件的元素直接跳过 def search([_item | tail], prefix), do: search(tail, prefix) end # 调用示例 StringStartsWith.search(["CaseDown", "YoHua", "CaseUp"], "Case") |> IO.inspect()
这个方案利用了Elixir的二进制模式匹配语法,<<prefix::binary-size(size)>>会匹配和前缀字节数相同的开头部分,同时通过when从句把size绑定为前缀的字节长度,让编译器能验证匹配的合法性。
两种方案对比:方案一代码更易读,适合大多数场景;方案二更贴近你最初想用模式匹配的思路,适合需要复杂匹配逻辑的场景。
内容的提问来源于stack exchange,提问作者DDStackoverflow
相关产品推荐
相关产品推荐

