gis*_*orx 0 string f# function
帮助我弄清楚如何处理文本
我有一个字符串,例如:“word1 number:word2”例如:“结果0:好”或“结果299:坏”
我需要打印未定义/低或高
当 string 为 null 时,打印 Undefined
当数字0-15时,打印Low
当数字 >15 时,打印 High
type GetResponse =
{
MyData: string voption
ErrorMessage: string voption }
val result: Result<GetResponse, MyError>
Run Code Online (Sandbox Code Playgroud)
然后我尝试:
MyData =
match result with
| Ok value ->
if (value.Messages = null) then
ValueSome "result: Undefined"
else
let result =
value.Messages.FirstOrDefault(
(fun x -> x.ToUpperInvariant().Contains("result")),
"Undefined"
)
if (result <> "Undefined") then
ValueSome result
else
errors.Add("We don't have any result")
ValueNone
| Error err ->
errors.Add(err.ToErrorString)
ValueNone
ErrorMessage =
if errors.Any() then
(errors |> String.concat ", " |> ValueSome)
else
ValueNone
Run Code Online (Sandbox Code Playgroud)
但我不知道gow检查字符串号,也许有某种方法可以打印这个而不需要十亿个if?
解析很快就会变得复杂。我建议使用FParsec来简化逻辑并避免错误。一个基本的解析器似乎可以满足您的需求:
open System
open FParsec
let parseWord =
manySatisfy Char.IsLetter
let parseValue =
parseWord // parse any word (e.g. "result")
>>. spaces1 // skip whitespace
>>. puint32 // parse an unsigned integer value
.>> skipChar ':' // skip colon character
.>> spaces // skip whitespace
.>> parseWord // parse any word (e.g. "Good")
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
type ParserResult = Undefined | Low | High
let parse str =
if isNull str then Result.Ok Undefined
else
match run parseValue str with
| Success (num, _ , _) ->
if num <= 15u then Result.Ok Low
else Result.Ok High
| Failure (errorMsg, _, _) ->
Result.Error errorMsg
parse null |> printfn "%A" // Ok Undefined
parse "result 0: Good" |> printfn "%A" // Ok Low
parse "result 299: Bad" |> printfn "%A" // Ok High
parse "invalid input" |> printfn "%A" // Error "Error in Ln: 1 Col: 9 ... Expecting: integer number"
Run Code Online (Sandbox Code Playgroud)
FParsec 肯定有一个学习曲线,但我认为它值得添加到您的工具带中。
小智 5
我同意 Brian 的观点,即解析很快就会变得非常棘手。但是,如果您有一些完善的输入格式,并且不太喜欢编写复杂的解析器,那么好的旧正则表达式可以派上用场;)
这是我对这个问题的看法 - 请注意,它还有很大的改进空间,这只是一个概念证明:
open System.Text.RegularExpressions
let test1 = "result 0: Good"
let test2 = "result 299: Bad"
let test3 = "some other text"
type ParserResult =
| Undefined
| Low of int
| High of int
let (|ValidNumber|_|) s =
//https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex?view=net-6.0
let rx = new Regex("(\w\s+)(\d+)\:(\s+\w)")
let matches = rx.Matches(s)
if matches.Count > 0 then
let groups = matches.[0].Groups |> Seq.toList
match groups with
| [_; _; a; _] -> Some (int a.Value)
| _ -> None
else
None
let parseMyString str =
match str with
| ValidNumber n when n < 16 -> Low n
| ValidNumber n -> High n
| _ -> Undefined
//let r = parseMyString test1
printfn "%A" (parseMyString test1)
printfn "%A" (parseMyString test2)
printfn "%A" (parseMyString test3)
Run Code Online (Sandbox Code Playgroud)
如果找到输入字符串的匹配项,则活动模式 ValidNumber 返回 Some 数字,否则返回 None。parseMyString 函数使用模式和防护来初始化最终的 ParserOutput 值。