我一直在使用库FsVerbalExpressions来编写一些函数。我正在努力以编程方式构建一个regEx。
例如,如果我有一个字符串"Int. Bus. Mach"
,我可以删除句点和空格,最后得到数组
let splitString = [|"Int"; "Bus"; "Mach"|]
我想要做的是从splitString
构建一个正则表达式,以便它的结果是:
let hardCoded =
VerbEx()
|> startOfLine
|> then' "Int"
|> anything
|> whiteSpace
|> then' "Bus"
|> anything
|> whiteSpace
|> then' "Mach"
hardCoded;;
val it : VerbEx =
^(Int)(.*)\s(Bus)(.*)\s(Mach) {MatchTimeout = -00:00:00.0010000;
Regex = ^(Int)(.*)\s(Bus)(.*)\s(Mach);
RegexOptions = None;
RightToLeft = false;}
我的问题是我不知道如何以编程方式构建它,因此,如果原始字符串是"This is a much bigger string"
,整个regEx是由代码而不是硬编码构建的。我可以使用
let test =
splitString
|> Array.map (fun thing -> VerbEx()
|> then' thing)
|> Array.toList
但这是VerbEx()
的列表,而不是上面的VerbEx()
个。{/ p>
有谁知道如何以编程方式FsVerbalExpressions
建立一个regEx?
提前感谢您的帮助!
答案 0 :(得分:5)
这样想:你需要从一些初始值VerbEx() |> startOfLine
开始,然后应用它重复一般形状为anything |> whitespace |> then' word
的模式。
您也可以用归纳术语来考虑它:您正在生成一系列值,其中每个值都表示为previousValue |> anything |> whitespace |> then' word
- 也就是说,系列中的每个下一个值都是先前的值,并应用了一些更改它。这个系列的最后一个元素是你的最终答案。
这样的操作 - 产生一系列值,其中每个值表示为前一个值的修改, - 传统上称为fold
。当然,F#具有执行此操作的标准库函数:
let applyChange previousValue word =
previousValue |> anything |> whitespace |> then' word
let initialValue = VerbEx() |> startOfLine
let finalAnswer = splitString |> Array.fold applyChange initialValue
或者你可以一起滚动:
let finalAnswer =
splitString
|> Array.fold
(fun previousValue word -> previousValue |> anything |> whitespace |> then' word)
(VerbEx() |> startOfLine)