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 压力。这根本不是最优的。你最好使用两个StartsWithStartsWith + 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#中字符串开头的模式匹配的主要内容,如果未能解决你的问题,请参考以下文章

我需要一个正则表达式结果,不包括匹配模式的开头和结尾的子字符串

python之正则表达式

如何编写正则表达式模式以匹配字符串结尾或字符串开头的货币符号

匹配除以单词开头之外的所有内容的模式[重复]

数据结构 字符串 模式匹配问题 KMP算法

正则表达式