【问题标题】:Unescape all nested quotes取消所有嵌套引号
【发布时间】:2011-03-06 22:40:09
【问题描述】:

我想取消转义字符串中的所有嵌套引号。以下示例以文字(C# 或 F#)样式的 .NET 字符串形式给出,而不是用引号括起来:

  • [(\"hello world\", 2); (\"goodbye\", 3)] 不变
  • [(\"hello\"world\", 2); (\"go\"o\"d\"bye\", 3)] 变为 [(\"hello\\\"world\", 2); (\"go\\\"o\\\"d\\\"bye\", 3)]

我不确定这是否可以使用Regex(pattern, "\\\"").Replace 完成,但我仍然是一个正则表达式新手,无法轻松找到解决方案。任何解决方案,如果可能的话,正则表达式,将不胜感激。

编辑

感谢到目前为止大家的反馈,我现在看到,由于没有区分开头和结尾的引号,因此语法模棱两可,我的方向无法工作。所以我会给出一个大图,希望有一个新的方向。

我正在开发一个将 F# 引号转换为 F# 源代码字符串的项目。所以我有一个函数source: Expr -> string,它应该产生一个字符串,当打印到像FSI这样的典型控制台时,它是有效的F#代码。对于这个问题,我希望改进Value 引用表达式的冲刺方式。目前我正在执行以下操作(请参阅从http://code.google.com/p/unquote/source/browse/trunk/Unquote/Sprint.fs 的第 312 行开始的实际代码):

match expr with
| Value(o, _) ->
  match o with
  | null -> "null"
  | _ -> sprintf "%A" o

但是,例如,我得到以下内容

> <@ "\r\"\n" @> |> source |> stdout.WriteLine;;
"
"
"
val it : unit = ()

而不是想要的

> <@ "\r\"\n" @> |> source |> stdout.WriteLine;;
"\r\"\n"
val it : unit = ()

如果我只需要考虑 Values 封装字符串,那么使用类似的东西会很容易

let unescape s =
    ["\\","\\\\"
     "\b","\\b"
     "\n","\\n" 
     "\r","\\r" 
     "\t","\\t"
     "\"", "\\\""]
    |> List.fold (fun (s:string) (before, after) -> s.Replace(before, after)) s

问题是,任何对象都可能是Value,包括那些具有sprint "%A" 使用的结构化格式的对象,我想尽可能多地利用它们(所以虽然我可以通过并处理有限的一组列表、数组、元组等情况,并不像我希望的那样通用):例如,冲刺 list&lt;string*int&gt; Value 需要特别小心,因为我们需要区分引号应该按字面意思显示字符串构造,而不是应该显示为转义序列。

欢迎任何想法,谢谢!

【问题讨论】:

  • 这是调试器的工件。反斜杠实际上并不存在于字符串中。使用 ToCharArray() 方法自己查看。或者文本可视化工具。
  • 嗨@Hans Passant - 我实际上并没有查看调试器输出,并且知道我给出的文字字符串产生的真实字符序列(我希望我不是不清楚,但是我真的想用反斜杠字符后跟引号字符替换嵌套的引号字符,但保持外部引号对不变。
  • @Stephen:这是什么语法? \"hello\"world\" 部分在该语法中真的有效吗(它会给出 "hello"world")?
  • 嗨@Maxim Gueivandov - 我正在使用带有转义序列的 C# / F# 文字字符串语法 (msdn.microsoft.com/en-us/library/h21280bw.aspx)。所以\" 代表"(所以是的,\"hello\"world\" 在打印时将是"hello"world")。抱歉,如果这令人困惑,我认为使用带有转义序列的文字字符串会使一切变得明确。
  • @Stephen,我说的是你的 [(string, int); (string, int)] 语法,这是你自己的东西吗?我只是不认识那个结构。

标签: .net regex string f# escaping


【解决方案1】:

我认为目前的问题无法做到这一点,因为您要处理的语法不明确。例如,无法判断是否:

[ (\"hello\"world\", 2); (\"good\"bye\", 3)]

应该变成包含两个元素的列表:

[ (\"hello\\\"world\", 2); (\"good\\\"bye\", 3)]

.. 或只有单个元素的列表(文本包含一些时髦的符号):

[ (\"hello\\\"world\\\", 2); (\\\"good\\\"bye\", 3)]

您似乎正在尝试对 F# Interactive 打印的输出做一些事情。也许有一些更好的方法来打印你需要的东西,这样你就可以避免歧义。可以加点大图吗?

如果您需要处理任何列表/元组数据结构,那么使用 F# 反射 API(参见 Microsoft.FSharp.Reflection 命名空间)编写它可能比解析 F# 输出更容易。 (或者您可以使用 API 编写您自己的明确打印机)

【讨论】:

  • 嗨@Tomas - 这是有道理的,我现在看到,由于开始和结束引号之间没有区别,语法是无可救药的模棱两可。我很乐意尽快编辑我的问题以提供全局。
  • 好的 - 我用大图编辑了问题,感谢您查看。
  • 感谢@Tomas - 如果我跟进此功能,我将听取您的建议并使用反射实现自定义通用打印机。
猜你喜欢
  • 2010-11-27
  • 2013-04-21
  • 1970-01-01
  • 1970-01-01
  • 2011-05-18
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多