如何将JSON中数值的小数位数限制为最多5位?
解决方案
针对你需要限制JSON数组中double类型数值最多5位小数的需求,这里提供三种可行方案,按推荐程度排序:
方案一:自定义JsonConverter(推荐)
通过Newtonsoft.Json的自定义转换器,在反序列化/序列化过程中精准处理目标数组的数值,避免正则误匹配问题。
实现步骤:
- 创建数组数值精度控制转换器:
public class DoubleArrayPrecisionConverter : JsonConverter<double[]> { private readonly int _decimalPlaces; public DoubleArrayPrecisionConverter(int decimalPlaces) { _decimalPlaces = decimalPlaces; } public override double[] ReadJson(JsonReader reader, Type objectType, double[] existingValue, bool hasExistingValue, JsonSerializer serializer) { if (reader.TokenType != JsonToken.StartArray) return existingValue; var valueList = new List<double>(); while (reader.Read() && reader.TokenType != JsonToken.EndArray) { if (double.TryParse(reader.Value?.ToString(), out var num)) { // 四舍五入到指定小数位,如需截断可替换为Math.Truncate(num * Math.Pow(10, _decimalPlaces)) / Math.Pow(10, _decimalPlaces) valueList.Add(Math.Round(num, _decimalPlaces)); } } return valueList.ToArray(); } public override void WriteJson(JsonWriter writer, double[] value, JsonSerializer serializer) { writer.WriteStartArray(); foreach (var num in value) { writer.WriteValue(Math.Round(num, _decimalPlaces)); } writer.WriteEndArray(); } }
- 在目标属性上绑定转换器:
[JsonProperty("s")] [JsonConverter(typeof(DoubleArrayPrecisionConverter), 5)] // 指定保留5位小数 public double[] Scale { get; set; } // 其他需要处理的数组属性同理 [JsonProperty("c")] [JsonConverter(typeof(DoubleArrayPrecisionConverter), 5)] public double[] Color { get; set; }
- 正常反序列化即可生效:
var jsonContent = File.ReadAllText("your_file.json"); var targetObj = JsonConvert.DeserializeObject<YourModelClass>(jsonContent);
该方案精准控制需要处理的属性,不会误修改其他数值或字符串中的数字,维护性强。
方案二:反序列化后手动处理属性
如果仅需处理少量属性,可直接在反序列化完成后遍历数组修改数值:
var jsonContent = File.ReadAllText("your_file.json"); var targetObj = JsonConvert.DeserializeObject<YourModelClass>(jsonContent); // 处理Scale数组 if (targetObj.Scale != null) { for (int i = 0; i < targetObj.Scale.Length; i++) { targetObj.Scale[i] = Math.Round(targetObj.Scale[i], 5); } } // 处理Color数组同理 if (targetObj.Color != null) { for (int i = 0; i < targetObj.Color.Length; i++) { targetObj.Color[i] = Math.Round(targetObj.Color[i], 5); } }
此方案简单直接,但属性较多时代码冗余度高。
方案三:修正正则处理(不推荐)
若坚持使用正则,需优化匹配规则避免误匹配字符串中的数字,示例如下:
var jsonContent = File.ReadAllText("your_file.json"); // 仅匹配数组中的数值(需确保JSON格式规范) var processedJson = Regex.Replace(jsonContent, @"(?<=[\[\s,])-?\d+\.\d+(?=[\s,\]])", match => { if (double.TryParse(match.Value, out var num)) { return Math.Round(num, 5).ToString(); } return match.Value; }); var targetObj = JsonConvert.DeserializeObject<YourModelClass>(processedJson);
注意:正则仅适合JSON结构固定、无字符串包含数字的场景,否则极易出现误替换。
内容的提问来源于stack exchange,提问作者defiant2369
相关产品推荐
相关产品推荐

