简体   繁体   English

将字符串转换为对列表:Kotlin

[英]Convert String into list of Pairs: Kotlin

Is there an easier approach to convert an Intellij IDEA environment variable into a list of Tuples?是否有更简单的方法将 Intellij IDEA 环境变量转换为元组列表?

My environment variable for Intellij is我的 Intellij 环境变量是

GROCERY_LIST=[("egg", "dairy"),("chicken", "meat"),("apple", "fruit")]

The environment variable gets accessed into Kotlin file as String.环境变量作为字符串访问到 Kotlin 文件中。

val g_list = System.getenv("GROCERY_LIST")

Ideally I'd like to iterate over g_list , first element being ("egg", "dairy") and so on.理想情况下,我想遍历g_list ,第一个元素是("egg", "dairy")等等。 And then ("egg", "dairy") is a tuple/pair然后("egg", "dairy")是一个元组/对

I have tried to split g_list by comma that's NOT inside quotes ie我试图用不在引号内的逗号分隔g_list

val splitted_list = g_list.split(",(?=(?:[^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*\$)".toRegex()).toTypedArray()

this gives me first element as [("egg", second element as "dairy")] and so on.这给了我第一个元素[("egg",第二个元素是"dairy")]等等。

Also created a data class and tried to map the string into data class using jacksonObjectMapper following this link:还创建了一个数据 class 并尝试使用jacksonObjectMapper 以下链接将 map 字符串转换为数据 class:

val mapper = jacksonObjectMapper()
val g_list = System.getenv("GROCERY_LIST")
val myList: List<Shopping> = mapper.readValue(g_list)

data class Shopping(val a: String, val b: String)

Never a good idea to use regex to match parenthesis.使用正则表达式来匹配括号从来都不是一个好主意。

I would suggest a step-by-step approach:我建议采用循序渐进的方法:

You could first match the name and the value by您可以先通过以下方式匹配名称和值

(\w+)=(.*)

There you get the name in group 1 and the value in group 2 without caring about any subsequent = characters that might appear in the value.您在第 1 组中获得名称,在第 2 组中获得值,而无需关心值中可能出现的任何后续=字符。

If you then want to split the value, I would get rid of start and end parenthesis first by matching by如果您随后想要拆分该值,我将首先通过匹配来摆脱开始和结束括号

(?<=\[\().*(?=\)\])

(or simply cut off the first and last two characters of the string, if it is always given it starts with [( and ends in )] ) (或者简单地切断字符串的第一个和最后两个字符,如果它总是以[()]开头)

Then get the single list entries from splitting by然后从拆分中获取单个列表条目

\),\(

(take care that the split operation also takes a regex, so you have to escape it) (注意拆分操作也需要一个正则表达式,所以你必须转义它)

And for each list entry you could split that simply by对于每个列表条目,您可以简单地将其拆分为

,\s*

or, if you want the quote character to be removed, use a match with或者,如果要删除引号字符,请使用匹配

\"(.*)\",\s*\"(.*)\"

where group 1 contains the key (left of equals sign) and group 2 the value (right of equals sign)其中第 1 组包含键(等号左侧),第 2 组包含值(等号右侧)

  1. You can create a regular expression to match all strings in your environmental variable.您可以创建一个正则表达式来匹配环境变量中的所有字符串。 Regex::findAll()
  2. Then loop through the strings while creating a list of Shopping objects.然后在创建Shopping对象列表时循环遍历字符串。
// Raw data set.
val groceryList: String = "[(\"egg\", \"dairy\"),(\"chicken\", \"meat\"),(\"apple\", \"fruit\")]"

// Build regular expression.
val regex = Regex("\"([\\s\\S]+?)\"")
val matchResult = regex.findAll(groceryList)
val iterator = matchResult.iterator()

// Create a List of `Shopping` objects.
var first: String = "";
var second: String = "";
val shoppingList = mutableListOf<Shopping>()
var i = 0;

while (iterator.hasNext()) {
    val value = iterator.next().value;

    if (i % 2 == 0) {
        first = value;
    } else {
        second = value;
        shoppingList.add(Shopping(first, second))
        first = ""
        second = ""
    }

    i++

}

// Print Shopping List.
for (s in shoppingList) {
    println(s)
}

// Output.
/*
    Shopping(a="egg", b="dairy")
    Shopping(a="chicken", b="meat")
    Shopping(a="apple", b="fruit")
*/

data class Shopping(val a: String, val b: String)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM