Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.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
Java 与使用带多个分隔符的拆分混淆_Java_Split - Fatal编程技术网

Java 与使用带多个分隔符的拆分混淆

Java 与使用带多个分隔符的拆分混淆,java,split,Java,Split,我正在练习阅读输入,然后标记它。 例如,如果我有[882337],我只想得到数字882和337。我尝试使用以下代码: String test = "[882,337]"; String[] tokens = test.split("\\[|\\]|,"); System.out.println(tokens[0]); System.out.println(tokens[1]); System.out.println(tokens[2]); 这是一种工作方

我正在练习阅读输入,然后标记它。 例如,如果我有[882337],我只想得到数字882和337。我尝试使用以下代码:

    String test = "[882,337]";
    String[] tokens = test.split("\\[|\\]|,");
    System.out.println(tokens[0]);
    System.out.println(tokens[1]);
    System.out.println(tokens[2]);
这是一种工作方式,输出为: (空行) 882 337

我不明白的是为什么令牌[0]是空的?我希望只有两个令牌,其中令牌[0]=882和令牌[1]=337

我查看了一些链接,但没有找到答案


谢谢你的帮助

Split拆分给定的
字符串
。如果您在“[”或“,”或“]”上拆分了“[882337]”,那么您实际上有:

  • 没什么
  • 882
  • 337
  • 没什么
但是,正如您所调用的
String.split(delimiter)
,这将调用
String.split(delimiter,limit)
,并且
限制为零

从:

limit
参数控制应用阵列的次数,从而影响结果阵列的长度。如果限制
n
大于零,则模式将最多应用
n-1次,数组长度将不大于
n
,数组的最后一个条目将包含最后一个匹配分隔符之外的所有输入。如果
n
为非正,则图案将被应用尽可能多的次数,并且阵列可以有任何长度如果
n
为零,则模式将被应用尽可能多的次数,数组可以有任何长度,尾随的空字符串将被丢弃。

(强调矿山)

因此在这个配置中,最终的空字符串被丢弃。因此,你只剩下你所拥有的


通常,要将这样的东西标记化,可以使用
replaceAll
split
的组合:

final String[] tokens = input.replaceAll("^\\[|\\]$").split(",");
这将首先去掉起始(
^[
)和结束(
]$
)括号,然后在
上拆分。这样,您就不必有某种迟钝的程序逻辑,从任意索引开始循环


另一种选择是,对于更复杂的标记化,可以使用
模式
——这可能有些过分,但在编写多个
replaceAll
链之前,需要记住这一点

首先,我们需要在正则表达式中定义我们想要的标记(而不是我们正在拆分的标记)——在这种情况下,它很简单,只是数字,所以
\d

因此,为了从任意
字符串
中提取所有仅数字(无千位/十进制分隔符)值,on将执行以下操作:

final List<Integer> tokens = new ArrayList<>();    <-- to hold the tokens
final Pattern pattern = Pattern.compile("\\d++");  <-- the compiled regex
final Matcher matcher = pattern.matcher(input);    <-- the matcher on input

while(matcher.find()) {                            <-- for each matched token
    tokens.add(Integer.parseInt(matcher.group())); <-- parse and `int` and store
}

final List tokens=new ArrayList() 这是因为每个分隔符都有一个“before”和“after”结果,即使它是空的。考虑

882337

你期望这会产生两个结果。 同样地,你期望

882337

生成三个,最后一个为空(假设您的限制足够大,或者假设您使用的几乎是任何其他语言/实现的
split()
)。从逻辑上说

,882337


必须生成四个,第一个和最后一个结果为空。这与您的情况完全相同,只是您有多个分隔符。

拆分字符串的符号如下:

String test = "[882,337]";
               ^   ^   ^
因为第一个字符与您的分隔符匹配,所以它留下的所有内容都将是第一个结果。第一个字母的左边是nothing,所以结果是空字符串

由于最后一个符号也与分隔符相匹配,因此结尾可能会出现相同的行为但是

因此,结果数组中不包括尾随的空字符串

请参阅。

拆分从一个对象创建两个(或多个)对象。例如,如果您按
拆分
a、b
您将得到
a
b

但是在
”的情况下,b“
您将得到
“b”
。你可以这样想:
存在于字符串的开头、结尾甚至所有字符之间:

“+”,“+”b“
->
”,b“
因此,如果我们在这个
”,“
上进行拆分,我们将得到左右部分:
“b”


类似的情况发生在
“a”
的情况下,最初的结果数组是
[“a”,“”]
,但这里
split
方法删除尾随的空字符串,只返回
[“a”]
(您可以使用
split(,,-1)
)来关闭此清除机制

所以如果

String test = "[882,337]";
String[] tokens = test.split("\\[|\\]|,");
您正在拆分:

     ""+"["+"882"+","+"337"+"]"+""
here:    ^         ^         ^
它首先创建数组
[“”、“882”、“337”和“”]
,然后删除尾随的空字符串,最后接收到:

[“”、“882”、“337”]

从结果数组的开头删除空字符串的唯一情况是

  • 您正在使用Java 8(或更高版本)和正则表达式上的拆分,该正则表达式的长度为零,类似于
    split(“”
    ),或者在每个
    x
    之前使用
    split((?=x)”)
    (更多信息见:)
  • 当这个空字符串是split方法的结果时。例如,
    “.split(”
    不删除
    ,更多信息请参见:

您应该了解如何使用。split()也可以使用简单字符串作为参数进行调用,如“,”。不过,请仔细阅读捕获组
String.split(delimiter,0)
带尾随空匹配项-因此这并不完全正确。
String test=“,882337;”;String[]tokens=test.split(“,”);System.out.println(令牌长度)产生3Ah,很有趣。谢谢你的解释。在处理这种情况时,我会从索引1开始对数组进行处理,以忽略前面的空字符串,还是有更优雅的方法呢?@SuperCow,如果您确实知道您的分隔符与位置为零的字符串相匹配(resultin