f#中字符串开头的模式匹配
Posted
技术标签:
【中文标题】f#中字符串开头的模式匹配【英文标题】:Pattern matching on the beginning of a string in f# 【发布时间】:2011-04-12 23:07:02 【问题描述】:我正在尝试匹配 f# 中字符串的开头。不确定我是否必须将它们视为字符列表或什么。任何建议将不胜感激。
这是我正在尝试做的伪代码版本
let text = "The brown fox.."
match text with
| "The"::_ -> true
| "If"::_ -> true
| _ -> false
所以,我想查看字符串的开头并进行匹配。请注意,我没有在字符串列表上匹配,只是将上述内容作为我想要做的事情的本质的想法。
【问题讨论】:
【参考方案1】:你也可以在模式上使用一个守卫:
match text with
| txt when txt.StartsWith("The") -> true
| txt when txt.StartsWith("If") -> true
| _ -> false
【讨论】:
这也是一个很好的例子,特别是如果您想在包含 = 和参数的开关上部分匹配。【参考方案2】:是的,如果您想使用匹配表达式,则必须将它们视为字符列表。
简单地转换字符串:
let text = "The brown fox.." |> Seq.toList
然后您可以使用匹配表达式,但您必须为每个字母使用字符(列表中元素的类型):
match text with
| 'T'::'h'::'e'::_ -> true
| 'I'::'f'::_ -> true
| _ -> false
正如 Brian 建议的参数化活动模式要好得多,有一些有用的模式 here(转到页面末尾)。
【讨论】:
虽然我更喜欢 Brian 使用活动模式的答案,但我想知道如果可能的前缀只有几个而且不长,这个答案是否会更有效。对此有何见解? 您必须创建一个临时数组和一个 F# 列表,因此可能会有很多对象会增加 GC 压力。这根本不是最优的。你最好使用两个StartsWith
或StartsWith
+ AP。
因为字符串已经是char seq
,你可以直接使用Seq.toList
。【参考方案3】:
参数化 active patterns 来救援!
let (|Prefix|_|) (p:string) (s:string) =
if s.StartsWith(p) then
Some(s.Substring(p.Length))
else
None
match "Hello world" with
| Prefix "The" rest -> printfn "Started with 'The', rest is %s" rest
| Prefix "Hello" rest -> printfn "Started with 'Hello', rest is %s" rest
| _ -> printfn "neither"
【讨论】:
+1。对于我们也想学习的活动模式来说,这是一个很好的例子! 这个答案很好地将组合活动模式应用于字符串匹配:***.com/questions/3686199/f-pattern-composition/… 这个答案很棒,但我必须承认我很困惑。匹配表达式中的“rest”值从何而来? 查看答案中的活动模式链接,部分活动模式部分。其余部分来自函数定义中的下划线 (_)。以上是关于f#中字符串开头的模式匹配的主要内容,如果未能解决你的问题,请参考以下文章
我需要一个正则表达式结果,不包括匹配模式的开头和结尾的子字符串