[英]Handling delimiter with escape characters in Java String.split() method
[英]Java String.split() regex for handling escaped delimeter and escaped escape characters
String testString = "a\\,b\\\\,c,d\\\\\\,e,f\\\\g";
String[] splitedString = test.split(PATTERN_STRING);
for (String string : splitedString) {
System.out.println(string);
}
這里我有一個String,它將List of String編碼為String,其中轉義字符是\\和分隔符,
注意:(由於Java代碼,示例中的反斜杠加倍)
反斜杠和逗號在原始字符串中轉義,結果字符串與逗號合並。 我需要一個正則表達式將此字符串拆分為原始的字符串列表。
以字符串為例
"a\,b\\,c,d\\\,e,f\\g"我需要得到這樣的字符串:
"a\\,b\\\\" "c" "d\\\\\\,e" "f\\\\g"
因此split的邏輯很簡單:只有當前面的反斜杠數是偶數時才用分隔符逗號分隔:0,2,4 ......只有在這種情況下這個逗號是分隔符。 如果逗號之前的反斜杠數是奇數,則轉義為逗號並且不應發生拆分。
對於這種情況,任何人都能幫助我使用適當的正則表達式嗎?
編輯
我知道這個正則表達式: (?<!\\\\\\\\),
將有助於用前面沒有反斜杠的逗號分隔字符串。 但在我的情況下,我需要拆分以防止逗號數為斜線之前的斜線。
感謝任何幫助。
如果它必須拆分,那么你可以嘗試類似的東西
split("(?<!(?<!\\\\)\\\\(\\\\{2}){0,1000000000}),")
我使用{0,1000000000}
而不是*
因為Java中的后視需要具有明顯的最大長度,並且1000000000
似乎已經足夠好了,除非你的文本中有超過1000000000
連續的\\\\
。
如果它不必split
那么你可以使用
Matcher m = Pattern.compile("(\\G.*?(?<!\\\\)(\\\\{2})*)(,|(?<!\\G)$)",
Pattern.DOTALL).matcher(testString);
while (m.find()) {
System.out.println(m.group(1));
}
\\\\G
表示上一次匹配的結束,或者如果這是Matcher的第一次迭代,並且字符串^
沒有先前的匹配開始。
但是實現起來最快且不那么熱衷的是編寫自己的解析器,它將使用像escaped
這樣的標志來表示當前檢查的字符是用\\
轉義的。
public static List<String> parse(String text) {
List<String> tokens = new ArrayList<>();
boolean escaped = false;
StringBuilder sb = new StringBuilder();
for (char ch : text.toCharArray()) {
if (ch == ',' && !escaped) {
tokens.add(sb.toString());
sb.delete(0, sb.length());
} else {
if (ch == '\\')
escaped = !escaped;
else
escaped = false;
sb.append(ch);
}
}
if (sb.length() > 0) {
tokens.add(sb.toString());
sb.delete(0, sb.length());
}
return tokens;
}
String testString = "a\\,b\\\\,c,d\\\\\\,e,f\\\\g";
String[] splitedString = testString
.split("(?<!(?<!\\\\)\\\\(\\\\{2}){0,1000000000}),");
for (String string : splitedString) {
System.out.println(string);
}
System.out.println("-----");
Matcher m = Pattern.compile("(\\G.*?(?<!\\\\)(\\\\{2})*)(,|(?<!\\G)$)",
Pattern.DOTALL).matcher(testString);
while (m.find()) {
System.out.println(m.group(1));
}
System.out.println("-----");
for (String s : parse(testString))
System.out.println(s);
輸出:
a\,b\\
c
d\\\,e
f\\g
-----
a\,b\\
c
d\\\,e
f\\g
-----
a\,b\\
c
d\\\,e
f\\g
嘗試,
我只是通過使用字符串操作來實現您的邏輯。
String string = "a\\,b\\\\,c,d\\\\\\,e,f\\\\g";
String finalString = "";
for(String i : string.split(",")){
int count = 0;
for(int j=0;j<i.length();j++)
if(i.charAt(j) == '\\')
count++;
finalString+=(count%2==0)?","+i+"$":","+i;
}
for(String finalAns: finalString.split("\\$")){
System.out.println(finalAns.replaceFirst(",", ""));
}
輸出:
a\,b\\
c
d\\\,e
f\\g
這將為您解決問題:
String[] splitedString = testString.split("(?<=[a-z])(\\\\{2})*,");
在這里,它是使用偶數(0是偶數這里)的\\
從字符串后面是,
對於拆分分隔符。
使用lookbehind
,它檢查\\
之前的最后一個字符是否是字母表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.