【问题标题】:Getting part of a JSON using Regex使用 Regex 获取 JSON 的一部分
【发布时间】:2020-11-12 12:56:59
【问题描述】:

我有一个 json 响应,但我在使用 Gson 或 Klaxon 时遇到了一些问题,因为我只需要一个(或多个,如果找到)字符串放入数组中。所以我有一个 JSON,例如:

"AddressLine":"Adress 1",
"AddressLine":"Adress 2",
...
"AddressLine":"Adress N",

我有一个功能:

private fun getArrayFromJson(response: String): Array<String> {
    val pattern = ".AddressLine.:\".*?\""
    val regex = Regex(pattern)
    val matchedResults = regex.findAll(response, 0)
    val result = mutableListOf<String>()
    matchedResults.forEach { p0 ->
        result.add(p0.value)
    }
    return result.toTypedArray()
}

主要问题是我只需要不带引号的“AddressLine”值。

但我不介意你帮我用 Klaxon 或 Gson 来做这件事。

如果需要,完整的 json 响应:

{
"response": {
"GeoObjectCollection": {
  "metaDataProperty": {
    "GeocoderResponseMetaData": {
      "Point": {
        "pos": "45.042529 38.975963"
      },
      "request": "45.042529,38.975963",
      "results": "10",
      "found": "2"
    }
  },
  "featureMember": [
    {
      "GeoObject": {
        "metaDataProperty": {
          "GeocoderMetaData": {
            "precision": "other",
            "text": "Иран, Западный Азербайджан",
            "kind": "province",
            "Address": {
              "country_code": "IR",
              "formatted": "Иран, Западный Азербайджан",
              "Components": [
                {
                  "kind": "country",
                  "name": "Иран"
                },
                {
                  "kind": "province",
                  "name": "Западный Азербайджан"
                }
              ]
            },
            "AddressDetails": {
              "Country": {
                "AddressLine": "Иран, Западный Азербайджан",
                "CountryNameCode": "IR",
                "CountryName": "Иран",
                "AdministrativeArea": {
                  "AdministrativeAreaName": "Западный Азербайджан"
                }
              }
            }
          }
        },
        "name": "Западный Азербайджан",
        "description": "Иран",
        "boundedBy": {
          "Envelope": {
            "lowerCorner": "44.032702 35.973002",
            "upperCorner": "47.392087 39.782107"
          }
        },
        "Point": {
          "pos": "44.868153 37.716911"
        }
      }
    },
    {
      "GeoObject": {
        "metaDataProperty": {
          "GeocoderMetaData": {
            "precision": "other",
            "text": "Иран",
            "kind": "country",
            "Address": {
              "country_code": "IR",
              "formatted": "Иран",
              "Components": [
                {
                  "kind": "country",
                  "name": "Иран"
                }
              ]
            },
            "AddressDetails": {
              "Country": {
                "AddressLine": "Иран",
                "CountryNameCode": "IR",
                "CountryName": "Иран"
              }
            }
          }
        },
        "name": "Иран",
        "boundedBy": {
          "Envelope": {
            "lowerCorner": "44.032702 24.872455",
            "upperCorner": "63.317241 39.782107"
          }
        },
        "Point": {
          "pos": "54.221233 33.733982"
        }
      }
    }
  ]
}
 }
}

我正在使用 Gson 从 json 中解析一个数组:

private fun getArrayFromJson() {
val jsonteststring = jsonResponse
val addressArrayType = object : TypeToken<Point>(){}.type
val addressVariants: Array<Point> = Gson().fromJson(jsonteststring, addressArrayType)

点类:

data class Point(val AddressLine: String){
override fun toString(): String {
    return AddressLine
    }
}

但我得到的只是一个例外:

Java.lang.RuntimeException:无法启动活动 ComponentInfo{com.example.mainproject/com.example.mainproject.PointProperties}:java.lang.ClassCastException:com.example.mainproject.Point 无法转换为 com.example .mainproject.Point[]

如果我使用的是我在互联网上找到的较小的 json 字符串:

"""[{"title":"Kotlin Tutorial #1","author":"bezkoder","categories":["Kotlin, Basic"]},
        {"title":"Kotlin Tutorial #2","author":"bezkoder","categories":["Kotlin, Practice"]}]"""

当我将TypeToken&lt;Point&gt; 更改为TypeToken&lt;Array&lt;Point&gt;&gt; 并将Point 中的AddressLine 重命名为title 时,它工作正常,所以我猜我的大json 并不那么容易解析

【问题讨论】:

  • I have some problems with using Gson or Klaxon有什么问题?我认为您应该解决这些问题,而不是使用正则表达式,并尝试使用 JSON 解析的标准。
  • @cutiko 将此添加到问题中

标签: android json kotlin


【解决方案1】:

Gson 的问题是您试图将整个 JSON 转换为 JSON 的一部分。您必须有一个完整的类来反映完整的 JSON,或者遍历 JSON,直到到达您需要的地方。

fun getAddressLines() : List<String> {
    val jsonObject = Gson().fromJson(RESPONSE, JsonObject::class.java)
    val response = jsonObject.getAsJsonObject("response")
    val geoObjectCollection = response.getAsJsonObject("GeoObjectCollection")
    val featureMember = geoObjectCollection.getAsJsonArray("featureMember")
    return featureMember.map { jsonElement ->
        val memberChild = jsonElement.asJsonObject
        val geoObject = memberChild.getAsJsonObject("GeoObject")
        val metaData = geoObject.getAsJsonObject("metaDataProperty")
        val geocoder = metaData.getAsJsonObject("GeocoderMetaData")
        val addressDetails = geocoder.getAsJsonObject("AddressDetails")
        val country = addressDetails.getAsJsonObject("Country")
        country.get("AddressLine").asString
    }
}

这将进入每个 JSON 对象并迭代数组以返回所有地址行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多