Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用模式获取子字符串并使用scala替换json值字段中的引号?_Scala_Apache Spark - Fatal编程技术网

如何使用模式获取子字符串并使用scala替换json值字段中的引号?

如何使用模式获取子字符串并使用scala替换json值字段中的引号?,scala,apache-spark,Scala,Apache Spark,我几乎没有像这样的json消息 {"column1":"abc","column2":"123","column3":qwe"r"ty,"column4":"abc123"} {"column1":"defhj","column2":"45","column3":asd"f"gh,"column4":"def12d"} 我需要为column3值的两边添加双引号,并使用scala将column3值中的双引号替换为单引号。您在上面的评论中提到过 我在卡夫卡有巨大的数据集。我正在尝试使用scala从

我几乎没有像这样的json消息

{"column1":"abc","column2":"123","column3":qwe"r"ty,"column4":"abc123"}
{"column1":"defhj","column2":"45","column3":asd"f"gh,"column4":"def12d"}

我需要为column3值的两边添加双引号,并使用scala将column3值中的双引号替换为单引号。

您在上面的评论中提到过


我在卡夫卡有巨大的数据集。我正在尝试使用scala从卡夫卡读取数据,并通过spark写入hdfs。我正在使用json解析器,但由于column3问题而无法解析。因此需要操纵消息以转换为json

因此,您一定在收集问题中提到的格式错误的JSON。我已经创建了一个列表作为

val kafkaMsg = List("""{"column1":"abc","column2":"123","column3":qwe"r"ty,"column4":"abc123"}""", """{"column1":"defhj","column2":"45","column3":asd"f"gh,"column4":"def12d"}""")
您正在通过Spark阅读它,所以您必须将RDD作为

val rdd = sc.parallelize(kafkaMsg)
您只需要对格式错误的文本json进行一些解析,使其成为有效的json字符串

val validJson = rdd.map(msg => msg.replaceAll("[}\"{]", "").split(",").map(_.split(":").mkString("\"", "\":\"", "\"")).mkString("{", ",", "}"))
validJson

{"column1":"abc","column2":"123","column3":"qwerty","column4":"abc123"}
{"column1":"defhj","column2":"45","column3":"asdfgh","column4":"def12d"}
您可以从validJson rdd创建数据帧,如下所示:

应该给你什么

+-------+-------+-------+-------+
|column1|column2|column3|column4|
+-------+-------+-------+-------+
|abc    |123    |qwerty |abc123 |
|defhj  |45     |asdfgh |def12d |
+-------+-------+-------+-------+
或者你可以根据自己的要求去做。

目标

使用scala为column3值的两侧添加双引号,并将column3值中的双引号替换为单引号

我建议使用RegEx,因为它更灵活

以下是解决方案:

val kafkaMsg = List("""{"column1":"abc","column2":"123","column3":qwe"r"ty,"column4":"abc123"}""", """{"column1":"defhj","column2":"45","column3":asd"f"gh,"column4":"def12d"}""", """{"column1":"defhj","column2":"45","column3":without-quotes,"column4":"def12d"}""")
val rdd = sc.parallelize(kafkaMsg)
val rePattern = """(^\{.*)("column3":)(.*)(,"column4":.*)""".r
val newRdd = rdd.map(r => 
    r match { 
        case rePattern(start, col3, col3Value, end) => (start + col3 + '"' + col3Value.replaceAll("\"", "'") + '"' + end)
        case _ => r }
    )

newRdd.foreach(println)
说明:

  • 第一个和第二个语句是rdd初始化

  • 第三行定义了正则表达式模式。您可能需要根据自己的情况进行调整

    正则表达式产生4组值(a()中的任何值都是一组值):

    • 以“{”开头的字符串,以及其后的任何字符串,直到我们遇到“column3”:
    • “第三栏”:本身
    • “column3”之后的内容:但在“column4”之前的内容:
    • 无论从什么开始,“专栏4”:
    我在下一个语句中使用这4个组

  • 迭代rdd,对正则表达式运行它,并对其进行更改:将双引号替换为单引号,并添加打开/关闭引号。如果不匹配,将返回原始字符串

    因为regex是用4个组定义的,所以我使用4个变量来映射匹配项:

    case rePattern(start, col3, col3Value, end) =>
    
    注意:代码不会检查值中是否有双引号,它只是运行更新。如果需要,您可以自行添加验证

  • 显示结果

  • 重要注意事项: 我使用的正则表达式严格链接到您的源字符串格式。请记住,您有JSON,所以不能保证键的顺序。因此,您可能会以“column4”(用作column3值结尾)结尾,而不是“column3”

    如果使用逗号作为键/值结尾,请确保不将其作为第3列值的一部分

    底线:您需要调整我的正则表达式,以正确标识第3列末尾的值


    希望有帮助。

    它们是否存储在文件中?您只需将它们作为字符串读取,解析它们并将其更改回json。spark的一些数据不会有效。kafka中有大量数据集。我正在尝试使用scala从kafka读取数据并通过spark写入hdfs。我使用json解析器,但由于column3问题而无法解析。因此需要操纵消息以更改为json。我可以在column3值中添加引号,但无法删除值中的引号。请查看下面的答案,看看这是否有帮助
    case rePattern(start, col3, col3Value, end) =>