如何在Scala中使用scala.util.JSON解析包含多行值的JSON文件
问题根因
标准JSON语法要求字符串值中的换行符必须显式转义为\n,不能直接出现原始换行符。你当前的代码直接将文件所有行用\n拼接后传入解析器,当hiveQuery字段值跨多行带原始换行时,不符合JSON语法规范,所以解析失败。
解决方案
方案1:预处理JSON文本,转义字符串内的原始换行
如果不想替换现有解析库,可以先对读取到的JSON文本做预处理,将双引号包裹的字符串内部的换行符转义为标准JSON要求的\n格式,修改后代码如下:
import scala.util.parsing.json.JSON val rawContent = scala.io.Source.fromFile(<file-path>).mkString // 正则匹配双引号包裹的字符串,转义内部的所有换行符 val escapedJson = """\"(.*?)\"""".r.replaceAllIn(rawContent, matched => { "\"" + matched.group(1).replaceAll("\\R", "\\\\n") + "\"" }) val parsedJsonText = JSON.parseFull(escapedJson).get.asInstanceOf[Map[String, Any]]
注意:该方案仅适用于JSON中没有转义双引号
\"的简单场景,如果JSON本身包含复杂转义字符,正则处理会出现边界问题,更推荐使用方案2。
方案2:替换为专业JSON解析库(生产环境首选)
Scala原生的JSON.parseFull功能极弱,且早已被标记为废弃特性,建议换用工业级JSON解析库,比如Jackson的Scala模块,可直接开启宽松解析特性兼容多行字符串场景:
- 首先引入sbt依赖:
libraryDependencies += "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.15.2"
- 调整解析代码:
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.scala.DefaultScalaModule import com.fasterxml.jackson.core.JsonParser.Feature val mapper = new ObjectMapper() mapper.registerModule(DefaultScalaModule) // 开启宽松解析,允许字符串中存在未转义的换行等控制字符 mapper.enable(Feature.ALLOW_UNQUOTED_CONTROL_CHARS) val parsedJsonText = mapper.readValue( scala.io.Source.fromFile(<file-path>).mkString, classOf[Map[String, Any]] )
该方案兼容性更强,也能处理各类复杂JSON格式场景。
内容的提问来源于stack exchange,提问作者VimalK
相关产品推荐
相关产品推荐

