【问题标题】:Replace long integers in raw json with strings用字符串替换原始 json 中的长整数
【发布时间】:2015-06-15 01:10:52
【问题描述】:

我正在寻找一种方法,将 17 位以上的所有整数用引号括在 json 格式的字符串中(在反序列化时基本上使它们成为字符串)。

有人在此处发布的 Javascript 中遇到相同问题 Convert all the integer value to string in JSON

我怀疑这里有一种使用 Regex.Replace() 的方法,但是需要了解两种语言之间的语法和正则表达式让我有点迷茫。

到目前为止我有:

        string pattern =  @"/:\s*(\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d+)\s*([,\}])/g";
        content = Regex.Replace(content,pattern, @":""{1}""{2}");

【问题讨论】:

  • 这里有一些示例数据:[ { "blingCompoundKey": { "id": 4510887396879241700, "dateTime": 1434087934451 }, "name": "Candy 5", "description": "" }, { "blingCompoundKey": { "id": 8351288136120734000, "dateTime": 1434267982997 }, "name": "test", "description": "" }] 我已经开始在这里单独测试正则表达式组件,因为它对初学者来说更容易regex101.com
  • 这可以在服务器端解决吗?
  • 考虑到 Javascript 最终处理 REST 输出和修改整数的频率,它可能(并且确实应该)是。目前,这将允许前端的开发继续进行。

标签: c# regex json


【解决方案1】:

零宽度负向前看/向后看 (https://msdn.microsoft.com/en-us/library/az24scfc(v=vs.110).aspx#grouping_constructs) 是您应该使用的,以确保开头或结尾没有引号。这样您在进行替换时就不需要知道确切的 JSON 格式:

string pattern = @"(?<![""\w])(\d{17,})(?![""\w])";
string content = Regex.Replace(content, pattern, "\"$1\"");

此解决方案不关心: 和数字之间是否有空格。它还将处理数组中的数字[ 0123456701234567, 0123456701234567 ] 或自行处理。

正则表达式仍然不是一个理想的解决方案,除非您知道将传递什么内容,因为一旦您在字符串值中包含一个数字,它就会中断,例如"abc 0123456701234567 def".

【讨论】:

  • 太好了,我还添加了一个允许负数的检查,我希望这不会引入任何新的不确定性(?&lt;![""\w])(-?\d{17,})(?![""\w])。正如你所说,这绝对不是任何人的长期解决方案 - 只是一些定义明确的测试数据的补丁,直到我的后端可以正确发送 id 作为字符串。
  • 这是一个很好的解决方案 - 但是否有理由在每个字符组中使用双引号字符两次 ([""\w])?
  • \w 包括数字字符,所以我认为你的前瞻和后瞻子表达式应该是 ["\D] (不匹配双引号或任何非数字数字)
  • 双引号用于转义 - 因为正则表达式倾向于使用大量反斜杠,我更喜欢@"..."。前瞻和后瞻是,因此它不会匹配abc01234678901234567def
【解决方案2】:

将所有长度超过 17 位的整数用 json 格式的字符串括在引号中

我会使用以下内容:

string pattern =  "[^\"\\d](\\d{17,})[^\"\\d]";
content = Regex.Replace(content,pattern, "\"$1\"");

第一行选择所有 17 位或更大的数值(并确保它们不是字符串)。 第二行将这 17 位数字包含在双引号中。

如果您的 JSON 被缩小,它会稍微改变正则表达式。我们可以使用,这将确保生成的 JSON 仍然有效。

string pattern =  ":(\\d{17,})";
content = Regex.Replace(content,pattern, "\"$1\"");

【讨论】:

  • 我不得不将您示例中的一些转义引号重新调整为以下内容:string pattern = @"[^""\d](\d{17,})[^""\d]"; content = Regex.Replace(content,pattern, @"$1"); 但它似乎替换了任一侧的字符(在这种情况下,它删除了 : 和 ,因为 json 有没有空格)。知道这是原始的正则表达式,还是我通过添加双引号在替换中更改的内容?
  • 我的错误 - 被删除的字符是我使用的正则表达式的简化版本(任何 17 位以上的数字),因为原始版本不匹配任何值,我希望看到它匹配。我将添加一些示例数据以说明问题
  • 我使用了您的示例数据,这是一个匹配的示例:regex101.com/r/oF6rC6/1 使用 .net,我将删除字符串前面的 @ 符号,并只使用双反引号,如我上次更新的答案。
  • 太棒了,我用各种转义字符迷惑了自己——删除了 @ 作品。我现在得到的输出是 {"blingCompoundKey":{"id""4510887396879241701""dateTime":1434087934451}, 。我认为正则表达式参数在两侧寻找潜在引号的 1 个字符也算作替换目标的一部分。然而,没有这些它也能工作——我现在可能不得不接受对已经引用的长整数不敏感。
  • 好的,看起来您正在处理缩小的 JSON(键/值之间没有空格)。在这种情况下,模式可能类似于":(\\d{17,})"
猜你喜欢
  • 2018-12-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-01
  • 1970-01-01
  • 2016-03-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多