+ 是“一个或多个”重复的正则表达式元字符,因此模式 -+ 是“一个或多个破折号”。这将允许您改用str.split("-+"),但您可能会得到一个空字符串作为第一个元素。
如果您只想删除所有-,那么您可以执行str = str.replace("-", "")。这使用replace(CharSequence, CharSequence) 方法,它执行文字String 替换,即不是正则表达式模式。
如果你想要一个String[],每个数字都在它自己的元素中,那么最简单的方法是分两步完成:首先删除所有非数字,然后使用零长度断言在不是字符串开头的任何地方分割(?!^)(防止将空字符串作为第一个元素)。如果你想要char[],那么你可以打电话给String.toCharArray()
最后,如果字符串可能很长,最好在find() 循环中使用java.util.regex.Matcher 来查找数字\d,或者使用带有分隔符\D* 的java.util.Scanner,即序列(可能是空的)非数字。这不会为您提供数组,但您可以使用循环来填充 List(请参阅Effective Java 2nd Edition,Item 25:Prefer lists to arrays)。
参考文献
片段
这里有一些例子来说明上述想法:
System.out.println(java.util.Arrays.toString(
"---4--5-67--8-9---".split("-+")
));
// [, 4, 5, 67, 8, 9]
// note the empty string as first element
System.out.println(
"---4--5-67--8-9---".replace("-", "")
);
// 456789
System.out.println(java.util.Arrays.toString(
"abcdefg".toCharArray()
));
// [a, b, c, d, e, f, g]
下一个例子首先删除所有非数字的\D,然后在除字符串(?!^)的开头之外的所有地方拆分,得到一个String[],每个都包含一个数字:
System.out.println(java.util.Arrays.toString(
"@*#^$4@!#5ajs67>?<{8_(9SKJDH"
.replaceAll("\\D", "")
.split("(?!^)")
));
// [4, 5, 6, 7, 8, 9]
这使用Scanner,以\D* 作为分隔符,将每个数字作为自己的标记,使用它来填充List<String>:
List<String> digits = new ArrayList<String>();
String text = "(&*!@#123ask45{P:L6";
Scanner sc = new Scanner(text).useDelimiter("\\D*");
while (sc.hasNext()) {
digits.add(sc.next());
}
System.out.println(digits);
// [1, 2, 3, 4, 5, 6]
split() 的常见问题
以下是处理String.split时的一些常见初学者问题:
第 1 课:split 采用正则表达式模式
这可能是最常见的初学者错误:
System.out.println(java.util.Arrays.toString(
"one|two|three".split("|")
));
// [, o, n, e, |, t, w, o, |, t, h, r, e, e]
System.out.println(java.util.Arrays.toString(
"not.like.this".split(".")
));
// []
这里的问题是 | 和 . 是正则表达式元字符,并且由于它们旨在按字面意思进行匹配,因此需要通过反斜杠进行转义,作为 Java 字符串文字是 "\\" .
System.out.println(java.util.Arrays.toString(
"one|two|three".split("\\|")
));
// [one, two, three]
System.out.println(java.util.Arrays.toString(
"not.like.this".split("\\.")
));
// [not, like, this]
第 2 课:split 默认丢弃尾随的空字符串
有时希望保留尾随空字符串(默认情况下会丢弃split):
System.out.println(java.util.Arrays.toString(
"a;b;;d;;;g;;".split(";")
));
// [a, b, , d, , , g]
请注意,c、e、f 的“缺失”值存在插槽,但h 和i 没有。要解决此问题,您可以对String.split(String regex, int limit) 使用否定的limit 参数。
System.out.println(java.util.Arrays.toString(
"a;b;;d;;;g;;".split(";", -1)
));
// [a, b, , d, , , g, , ]
您也可以使用 n 的正数 limit 最多应用该模式 n - 1 次(即,结果不超过 n 数组中的元素)。
零宽度匹配split 示例
这里有更多关于零宽度匹配结构的拆分示例;这可用于拆分字符串,但也可以保留“分隔符”。
简单的分句,保留标点符号:
String str = "Really?Wow!This.Is.Awesome!";
System.out.println(java.util.Arrays.toString(
str.split("(?<=[.!?])")
)); // prints "[Really?, Wow!, This., Is., Awesome!]"
使用\G将长字符串分成固定长度的部分
String str = "012345678901234567890";
System.out.println(java.util.Arrays.toString(
str.split("(?<=\\G.{4})")
)); // prints "[0123, 4567, 8901, 2345, 6789, 0]"
在大写字母之前拆分(第一个除外!)
System.out.println(java.util.Arrays.toString(
"OhMyGod".split("(?=(?!^)[A-Z])")
)); // prints "[Oh, My, God]"
下面的相关问题提供了各种示例。
参考文献
相关问题