示例输入:
RC23
CC23QQ21HD32
BPOASDf91A5HH123
示例输出:
[RC,23]
[CC,23,QQ,21,HD,32]
[BPOASDf,91,A,5,HH,123]
alpha部分和数字部分的长度不固定。
我知道如何将split()与//.' ' ' '([a-z])
这样的正则表达式一起使用,但是虽然我检查了split()
Java API但我找不到任何可以帮助我解决这个问题的东西。
有没有办法使用split()
来执行此操作?或者我需要使用另一种方法来分割这些字符串。
任何帮助都将不胜感激。
答案 0 :(得分:4)
试试这个正则表达式:"((?<=[a-zA-Z])(?=[0-9]))|((?<=[0-9])(?=[a-zA-Z]))"
这是一个正在运行的示例:http://ideone.com/c02rmM
{
...
String someString = "CC23QQ21HD32";
String regex = "((?<=[a-zA-Z])(?=[0-9]))|((?<=[0-9])(?=[a-zA-Z]))";
System.out.println(Arrays.asList(someString.split(regex)));
//outputs [CC, 23, QQ, 21, HD, 32]
...
}
正则表达式使用预测 (?=ValueToMatch)
,查看背后 (?<=ValueToMatch)
。
它的前半部分(在|之前)询问:&#34;前一个字符是否为(?<=[a-zA-Z])
字母?下一个字符是数字(?=[0-9])
吗?&#34;如果两者都为真,则它将字符串与正则表达式匹配。
该正则表达式的后半部分是相反的。它问:&#34;前一个字符是数字(?<=[0-9])
?下一个字符是字母吗? (?=[a-zA-Z])
&#34;,如果两者都属实,它将再次匹配。
通常split()会删除正则表达式匹配的字符。即使对于这个正则表达式,这仍然是正确的。但是,由于正则表达式匹配0宽度前瞻,因此不会删除您正在寻找的实际字符。
查看Adam Paynter的答案,了解更多关于 lookaheads 和了解背后的信息:how to split string with some separator but without removing that separator in Java?
答案 1 :(得分:1)
您可以匹配1个或多个连续的字母字符或1个或多个连续的数字字符。一旦序列中断停止匹配,则存储序列然后重新开始。非字字符将被完全忽略。
修改:我在下面创建了一个简单的性能测试,以显示使用String.split()
和Pattern.matcher()
之间的速度。拆分版本比匹配器+循环版本快2.5倍。
private static String[] splitAlphaNumeric(String str) {
return str.split("(?i)((?<=[A-Z])(?=\\d))|((?<=\\d)(?=[A-Z]))");
}
import java.util.*;
import java.util.regex.*;
public class SplitAlphaNumeric {
private static final Pattern ALPH_NUM_PAT = Pattern.compile("[0-9]+|[A-Z]+");
private static List<String> input = Arrays.asList(
"RC23",
"CC23QQ21HD32",
"BPOASDf91A5HH123"
);
public static void main(String[] args) {
System.out.printf("Execution time: %dns%n", testMatch());
System.out.printf("Execution time: %dns%n", testSplit());
}
public static long testMatch() {
System.out.println("Begin Test 1...");
long start = System.nanoTime();
for (String str : input) {
System.out.printf("%-16s -> %s%n", str, parse(str));
}
long end = System.nanoTime();
return end - start;
}
public static long testSplit() {
System.out.println("\nBegin Test 2...");
long start = System.nanoTime();
for (String str : input) {
System.out.printf("%-16s -> %s%n", str, parse2(str));
}
long end = System.nanoTime();
return end - start;
}
private static List<String> parse(String str) {
List<String> parts = new LinkedList<String>();
Matcher matcher = ALPH_NUM_PAT.matcher(str);
while (matcher.find()) {
parts.add(matcher.group());
}
return parts;
}
private static List<String> parse2(String str) {
return Arrays.asList(str.split("(?i)((?<=[A-Z])(?=\\d))|((?<=\\d)(?=[A-Z]))"));
}
}
Begin Test 1...
RC23 -> [RC, 23]
CC23QQ21HD32 -> [CC, 23, QQ, 21, HD, 32]
BPOASDf91A5HH123 -> [BPOASD, 91, A, 5, HH, 123]
Execution time: 4879125ns
Begin Test 2...
RC23 -> [RC, 23]
CC23QQ21HD32 -> [CC, 23, QQ, 21, HD, 32]
BPOASDf91A5HH123 -> [BPOASDf, 91, A, 5, HH, 123]
Execution time: 1953349ns
答案 2 :(得分:0)
您可以使用前瞻,例如&#34; ((?<=%1[0-9]+)|(?=%1[0-9]+))
&#34;