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

How to do non standard string replacement in f#?

我是 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)"

有什么方便的方法可以解决这个问题吗?提前致谢。

您可以使用 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)"

Regex.Replace是你的朋友:

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

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

对于已接受答案但使用正则表达式有一定开销的旧线程上的 necro 发布表示歉意,并且使用列表的天真的迭代解决方案在性能方面可能更胜一筹:

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