Java 如何拆分多维数组字符串
如何从数组的字符串中拆分和检索数据 对象有一个可以是多维的变量数组 演示输入字符串Java 如何拆分多维数组字符串,java,arrays,regex,multidimensional-array,kotlin,Java,Arrays,Regex,Multidimensional Array,Kotlin,如何从数组的字符串中拆分和检索数据 对象有一个可以是多维的变量数组 演示输入字符串 CONTAINER [1, "one", false, [CONTAINER [2, "two", false]], 42, true] 预期结果 CONTAINER 1 "one" false [CONTAINER [2, "two", false]] 42 true 然后,我将采取第5组,并再次运行它,以获得其余的对象 拆分字符串以获取内部数据的好方法是什么 可以使用正则表达式吗 如果另一种布局更容易,我
CONTAINER [1, "one", false, [CONTAINER [2, "two", false]], 42, true]
预期结果
CONTAINER
1
"one"
false
[CONTAINER [2, "two", false]]
42
true
然后,我将采取第5组,并再次运行它,以获得其余的对象
拆分字符串以获取内部数据的好方法是什么
可以使用正则表达式吗
如果另一种布局更容易,我可以选择以不同的方式格式化字符串。最简单的方法是使用拆分:
val input = """CONTAINER [1, "one", false, [CONTAINER [2, "two", false]], 42, true]"""
input.split(" ", "[", ",", "]").filter {
it != ""
}.forEach {
println(it)
}
输出:
CONTAINER
1
"one"
false
CONTAINER
2
"two"
false
42
true
由于可以手动识别根容器中的数组,因此我可以用普通方括号替换方括号,以便于检索数据
input = if(input.endsWith("]]]")) replaceLast(input, "]]]", "])]") else replaceLast(input, "]], ", "]), ")
val arraySplit = input.split("(", ")")
从那里可以使用正则表达式模式来迭代嵌套,以检索和替换所有后续容器
private val pattern = Pattern.compile("([A-Z]+\\s\\[[^\\[\\]]+])")
没有我想要的那么干净,但它很实用。主要关注点是支持多个嵌套层,例如在本例中:
输入
输出
CONTAINER [1, "one", false, [$array], 42, true]
$array = $4, $2, $3
$0 = CONTAINER [3, "three"]
$1 = CONTAINER [false]
$2 = CONTAINER [2, "string", false]
$3 = CONTAINER [4]
$4 = CONTAINER [2, "two", $0, $1, true]
例如,感谢@Alexey Soshin
全班:
import org.junit.Assert
import org.junit.Test
import java.util.regex.Pattern
class ContainerTest {
private val pattern = Pattern.compile("([A-Z]+\\s\\[[^\\[\\]]+])")
/**
* Checks if string contains a full array in the middle or at the end of the container values
* @return whether a verified container contains an array
*/
private fun hasArray(string: String): Boolean {
return string.contains(", [") && (string.contains("]], ") || string.endsWith("]]]"))
}
/**
* Replaces last occurrence of a substring
* Credit: https://stackoverflow.com/a/16665524/2871826
*/
private fun replaceLast(string: String, substring: String, replacement: String): String {
val index = string.lastIndexOf(substring)
return if (index == -1) string else string.substring(0, index) + replacement + string.substring(index + substring.length)
}
/**
* Splits root container and returns string contents of it's array
*/
private fun extractArray(string: String): String {
if(!hasArray(string))
return ""
//Replace square brackets of array with regular so it's easier to differentiate
var input = string
input = input.replaceFirst(", [", ", (")
input = if(input.endsWith("]]]")) replaceLast(input, "]]]", "])]") else replaceLast(input, "]], ", "]), ")
val arraySplit = input.split("(", ")")
return arraySplit[1]//Always the second index
}
private fun replaceArray(input: String, array: String): String {
return input.replaceFirst(array, "\$array")
}
/**
* Iterates pattern matching for the remainder containers
* @return list of individual container strings
*/
private fun extractContainers(string: String): ArrayList<String> {
var array = string
val containers = arrayListOf<String>()
var index = 0
//Nature of pattern matches deepest level first then works it's way upwards
while(array.contains("[")) {//while has more containers
val matcher = pattern.matcher(array)
while (matcher.find()) {
val match = matcher.group()
containers.add(match)
array = array.replace(match, "\$${index++}")
}
}
return containers
}
/**
* Replaces container strings with placeholder indices
*/
private fun replaceContainers(string: String, containers: ArrayList<String>): String {
var array = string
containers.forEachIndexed { index, s -> array = array.replaceFirst(s, "\$$index") }
return array
}
/**
* Splits container variables
* @return array of values
*/
private fun getVariables(string: String): List<String> {
return string.substring(11, string.length - 1).split(", ")
}
@Test
fun all() {
val input = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"], CONTAINER [false], true], CONTAINER [2, \"string\", false], CONTAINER [4]], 42, true]"//"""CONTAINER [1, "one", false, [CONTAINER [2, "two", false]], 42, true]"""
if(hasArray(input)) {
val array = extractArray(input)
val first = replaceArray(input, array)
val containers = extractContainers(array)
val final = replaceContainers(array, containers)
println("$first ${getVariables(first)}")
println("\$array = $final")
containers.forEachIndexed { index, s -> println("\$$index = $s ${getVariables(s)}") }
}
}
private val emptyLast = "CONTAINER [1, \"one\", false, []]"
private val oneLast = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\"]]]"
private val twoLast = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]]]"
private val threeLast = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]]]"
private val empty = "CONTAINER [1, \"one\", false, [], 42]"
private val one = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\"]], 42]"
private val two = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]], 42]"
private val three = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]], 42]"
@Test
fun hasArray() {
Assert.assertFalse(hasArray(emptyLast))
Assert.assertTrue(hasArray(oneLast))
Assert.assertTrue(hasArray(twoLast))
Assert.assertFalse(hasArray(empty))
Assert.assertTrue(hasArray(one))
Assert.assertTrue(hasArray(two))
}
@Test
fun extractArray() {
Assert.assertTrue(extractArray(empty).isEmpty())
Assert.assertTrue(extractArray(emptyLast).isEmpty())
Assert.assertEquals(extractArray(oneLast), "CONTAINER [2, \"two\"]")
Assert.assertEquals(extractArray(twoLast), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]")
Assert.assertEquals(extractArray(threeLast), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]")
Assert.assertEquals(extractArray(one), "CONTAINER [2, \"two\"]")
Assert.assertEquals(extractArray(two), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]")
Assert.assertEquals(extractArray(three), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]")
}
@Test
fun replaceArray() {
val last = "CONTAINER [1, \"one\", false, [\$array]]"
val first = "CONTAINER [1, \"one\", false, [\$array], 42]"
Assert.assertEquals(replaceArray(oneLast, "CONTAINER [2, \"two\"]"), last)
Assert.assertEquals(replaceArray(twoLast, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]"), last)
Assert.assertEquals(replaceArray(threeLast, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]"), last)
Assert.assertEquals(replaceArray(one, "CONTAINER [2, \"two\"]"), first)
Assert.assertEquals(replaceArray(two, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]"), first)
Assert.assertEquals(replaceArray(three, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]"), first)
}
@Test
fun extractContainers() {
Assert.assertEquals(extractContainers("CONTAINER [2, \"two\"]").size, 1)
Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]").size, 3)
Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]").size, 4)
Assert.assertEquals(extractContainers("CONTAINER [2, \"two\"]").size, 1)
Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]").size, 3)
Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]").size, 4)
}
}
对于正则表达式来说,这是一个非常糟糕的用例。如果您的容器对象可以具有任意深度的自嵌套,那么可能没有模式可以一致地描述它。因为您已经在使用Java,所以用几行单独的代码来处理这个对象应该非常简单。这有点离题,但实际上是否有一个[就在容器之前]?它看起来像[应该跟在单词CONTAINER后面。@CAustin我最初也这么认为,我不知道如何在不影响内部分隔符的情况下按分隔符分割,你能举个例子吗?正则表达式似乎更适合,因为它是一种模式,我只是不知道正则表达式中递归的程度。@zhh是的,因为它是数组中容器的数组变量。是否要解析整数?无法确定42是否与输出中的第一个或第二个容器分开。我不知道split可以接受多个参数,这有助于找到解决方案,谢谢。
import org.junit.Assert
import org.junit.Test
import java.util.regex.Pattern
class ContainerTest {
private val pattern = Pattern.compile("([A-Z]+\\s\\[[^\\[\\]]+])")
/**
* Checks if string contains a full array in the middle or at the end of the container values
* @return whether a verified container contains an array
*/
private fun hasArray(string: String): Boolean {
return string.contains(", [") && (string.contains("]], ") || string.endsWith("]]]"))
}
/**
* Replaces last occurrence of a substring
* Credit: https://stackoverflow.com/a/16665524/2871826
*/
private fun replaceLast(string: String, substring: String, replacement: String): String {
val index = string.lastIndexOf(substring)
return if (index == -1) string else string.substring(0, index) + replacement + string.substring(index + substring.length)
}
/**
* Splits root container and returns string contents of it's array
*/
private fun extractArray(string: String): String {
if(!hasArray(string))
return ""
//Replace square brackets of array with regular so it's easier to differentiate
var input = string
input = input.replaceFirst(", [", ", (")
input = if(input.endsWith("]]]")) replaceLast(input, "]]]", "])]") else replaceLast(input, "]], ", "]), ")
val arraySplit = input.split("(", ")")
return arraySplit[1]//Always the second index
}
private fun replaceArray(input: String, array: String): String {
return input.replaceFirst(array, "\$array")
}
/**
* Iterates pattern matching for the remainder containers
* @return list of individual container strings
*/
private fun extractContainers(string: String): ArrayList<String> {
var array = string
val containers = arrayListOf<String>()
var index = 0
//Nature of pattern matches deepest level first then works it's way upwards
while(array.contains("[")) {//while has more containers
val matcher = pattern.matcher(array)
while (matcher.find()) {
val match = matcher.group()
containers.add(match)
array = array.replace(match, "\$${index++}")
}
}
return containers
}
/**
* Replaces container strings with placeholder indices
*/
private fun replaceContainers(string: String, containers: ArrayList<String>): String {
var array = string
containers.forEachIndexed { index, s -> array = array.replaceFirst(s, "\$$index") }
return array
}
/**
* Splits container variables
* @return array of values
*/
private fun getVariables(string: String): List<String> {
return string.substring(11, string.length - 1).split(", ")
}
@Test
fun all() {
val input = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"], CONTAINER [false], true], CONTAINER [2, \"string\", false], CONTAINER [4]], 42, true]"//"""CONTAINER [1, "one", false, [CONTAINER [2, "two", false]], 42, true]"""
if(hasArray(input)) {
val array = extractArray(input)
val first = replaceArray(input, array)
val containers = extractContainers(array)
val final = replaceContainers(array, containers)
println("$first ${getVariables(first)}")
println("\$array = $final")
containers.forEachIndexed { index, s -> println("\$$index = $s ${getVariables(s)}") }
}
}
private val emptyLast = "CONTAINER [1, \"one\", false, []]"
private val oneLast = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\"]]]"
private val twoLast = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]]]"
private val threeLast = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]]]"
private val empty = "CONTAINER [1, \"one\", false, [], 42]"
private val one = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\"]], 42]"
private val two = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]], 42]"
private val three = "CONTAINER [1, \"one\", false, [CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]], 42]"
@Test
fun hasArray() {
Assert.assertFalse(hasArray(emptyLast))
Assert.assertTrue(hasArray(oneLast))
Assert.assertTrue(hasArray(twoLast))
Assert.assertFalse(hasArray(empty))
Assert.assertTrue(hasArray(one))
Assert.assertTrue(hasArray(two))
}
@Test
fun extractArray() {
Assert.assertTrue(extractArray(empty).isEmpty())
Assert.assertTrue(extractArray(emptyLast).isEmpty())
Assert.assertEquals(extractArray(oneLast), "CONTAINER [2, \"two\"]")
Assert.assertEquals(extractArray(twoLast), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]")
Assert.assertEquals(extractArray(threeLast), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]")
Assert.assertEquals(extractArray(one), "CONTAINER [2, \"two\"]")
Assert.assertEquals(extractArray(two), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]")
Assert.assertEquals(extractArray(three), "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]")
}
@Test
fun replaceArray() {
val last = "CONTAINER [1, \"one\", false, [\$array]]"
val first = "CONTAINER [1, \"one\", false, [\$array], 42]"
Assert.assertEquals(replaceArray(oneLast, "CONTAINER [2, \"two\"]"), last)
Assert.assertEquals(replaceArray(twoLast, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]"), last)
Assert.assertEquals(replaceArray(threeLast, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]"), last)
Assert.assertEquals(replaceArray(one, "CONTAINER [2, \"two\"]"), first)
Assert.assertEquals(replaceArray(two, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]"), first)
Assert.assertEquals(replaceArray(three, "CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]"), first)
}
@Test
fun extractContainers() {
Assert.assertEquals(extractContainers("CONTAINER [2, \"two\"]").size, 1)
Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]").size, 3)
Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]").size, 4)
Assert.assertEquals(extractContainers("CONTAINER [2, \"two\"]").size, 1)
Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"]").size, 3)
Assert.assertEquals(extractContainers("CONTAINER [2, \"two\", CONTAINER [3, \"three\"]], CONTAINER [4, \"four\"], CONTAINER [5, \"five\"]").size, 4)
}
}