Dav*_*ite 3 f# pattern-matching
我对F#很新,但过去几周都在阅读参考资料.我希望处理用户提供的输入字符串,识别和分离组成元素.例如,对于此输入:
XYZ酒店:入住6晚,每晚220欧元,另加17.5%的税
输出应该类似于元组列表:
[("XYZ",Word); ("酒店:",Word);
("6",数字); ("夜晚",Word);
("at",运营商); ("220",数字);
("EUR",CurrencyCode); ("/",运营商); ("夜",Word);
("加",运营商); ("17.5",数字); ("%", 百分); ("税",Word)]
由于我正在处理用户输入,它可能是任何东西.因此,期望用户遵守语法是不可能的.我想识别数字(可能是整数,浮点数,负数......),度量单位(可选,但可以包括SI或Imperial物理单位,货币代码,例如"night/s"中的计数) ,数学运算符(作为数学符号或包括"at""per","of","discount"等的单词)以及所有其他单词.
我的印象是我应该使用主动模式匹配 - 这是正确的吗? - 但我不确定如何开始.任何指向适当参考材料或类似示例的指针都会很棒.
我使用FParsec库汇总了一个示例.这个例子根本不健壮,但它给出了如何使用FParsec的非常好的图片.
type Element =
| Word of string
| Number of string
| Operator of string
| CurrencyCode of string
| PerCent of string
let parsePerCent state =
(parse {
let! r = pstring "%"
return PerCent r
}) state
let currencyCodes = [|
pstring "EUR"
|]
let parseCurrencyCode state =
(parse {
let! r = choice currencyCodes
return CurrencyCode r
}) state
let operators = [|
pstring "at"
pstring "/"
|]
let parseOperator state =
(parse {
let! r = choice operators
return Operator r
}) state
let parseNumber state =
(parse {
let! e1 = many1Chars digit
let! r = opt (pchar '.')
let! e2 = manyChars digit
return Number (e1 + (if r.IsSome then "." else "") + e2)
}) state
let parseWord state =
(parse {
let! r = many1Chars (letter <|> pchar ':')
return Word r
}) state
let elements = [|
parseOperator
parseCurrencyCode
parseWord
parseNumber
parsePerCent
|]
let parseElement state =
(parse {
do! spaces
let! r = choice elements
do! spaces
return r
}) state
let parseElements state =
manyTill parseElement eof state
let parse (input:string) =
let result = run parseElements input
match result with
| Success (v, _, _) -> v
| Failure (m, _, _) -> failwith m
Run Code Online (Sandbox Code Playgroud)