如何在f#中进行非标准字符串替换?

时间:2019-05-14 15:38:00

标签: f# f#-interactive

我是f#的新手,想用它来改变命题逻辑公式字符串的格式:

我想用字符串“ next(a)”替换“ aX”,其中'a'是[a..z]的元素,而'X'是大写的X'字符。

我找到的所有来源,例如https://www.dotnetperls.com/replace-fs可以将一个字符串替换为另一个字符串,

let s = "a & b & c & aX & !bX"
let sReplaced = s.Replace("X", "next()") // val it : string = "a & b & c & anext() & !bnext()"

在这种情况下,您不能将原始字符放在中间,或者无法按字符工作,例如。

let sArray = s.ToCharArray()

for c in 0 .. sArray.Length - 1 do
    if sArray.[c] = 'X' then
        sArray.[c-2] <- '('
        sArray.[c] <- ')'
let sArrayResult = new string(sArray) // val sArrayResult : string = "a & b & c &(a) & (b)"

仅允许输出字符串具有相同的长度。

“ a&b&c&aX&!bX”

应替换为

“ a&b&c&next(a)&!next(b)”

是否有一些方便的方法来解决此问题?预先感谢。

3 个答案:

答案 0 :(得分:2)

您可以使用MatchEvaluator

open System.Text.RegularExpressions

let s = "a & b & c & aX & !bX"
Regex.Replace(s, "([a-z]X)", fun m -> "next(" + m.Value.TrimEnd('X') + ")")
- ;;
val it : string = "a & b & c & next(a) & !next(b)"

答案 1 :(得分:2)

使用可接受的答案在旧线程上坏死发布的道歉,但使用正则表达式会产生一定的开销,而使用列表的幼稚迭代解决方案在性能方面可能会比较好:

let strXToNext (s : string) =
    let next c a =
        ')' :: c :: '(' :: 't' :: 'x' :: 'e' :: 'n' :: a
    let rec replX a = function
        | [] -> List.rev a
        | c :: 'X' :: cs when c >= 'a' && c <= 'z' ->
            replX (next c a) cs
        | c :: cs -> replX (c :: a) cs
    s |> List.ofSeq
      |> replX []
      |> List.toArray
      |> fun a -> Core.string a

答案 2 :(得分:1)

Regex.Replace是你的朋友:

open System.Text.RegularExpressions
let myReplace s =
    Regex.Replace (s, ".X", fun mat -> sprintf "next(%c)" <| mat.ToString().[0])

您可以将.更改为[a-z]或任何与您称为任意字符匹配的模式。