[英]Java- Split String which is alphanumeric
輸入示例:
RC23
CC23QQ21HD32
BPOASDf91A5HH123
輸出示例:
[RC,23]
[CC,23,QQ,21,HD,32]
[BPOASDf,91,A,5,HH,123]
字母和數字部分的長度不固定。
我知道如何將split()與//.' ' ' '([az])
正則表達式結合使用//.' ' ' '([az])
//.' ' ' '([az])
但是盡管我檢查了split()
Java API,但找不到任何可以幫助我解決此問題的東西。
有沒有辦法使用split()
做到這一點? 或者我需要使用另一種方法來拆分這些字符串。
任何幫助,將不勝感激。
試試這個正則表達式: "((?<=[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)
。
它的前半部分(在|之前)問:“上一個字符是字母(?<=[a-zA-Z])
嗎?下一個字符是數字(?=[0-9])
嗎?” 如果兩者都為真,則將字符串與正則表達式匹配。
該正則表達式的后半部分正相反。 它詢問:“前一個字符是數字(?<=[0-9])
嗎?下一個字符是字母嗎? (?=[a-zA-Z])
”,並且如果兩個都為真正。
通常,split()會刪除正則表達式匹配的字符。 即使對於此正則表達式也是如此。 但是,由於正則表達式與0寬前瞻匹配,因此不會刪除您要查找的實際字符。
請查看Adam Paynter的答案,以獲取有關先行和后退的更多信息 : 如何在不使用Java刪除分隔符的情況下使用一些分隔符拆分字符串?
您可以匹配1個或多個連續的字母字符或1個或多個連續的數字字符。 序列中斷后,停止匹配,然后存儲序列,然后重新開始。 非單詞字符將被完全忽略。
編輯:我在下面創建了一個簡單的性能測試,以顯示使用String.split()
和Pattern.matcher()
之間的速度。 拆分版本比matcher + loop版本快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
您可以使用前瞻,例如“ ((?<=%1[0-9]+)|(?=%1[0-9]+))
”
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.