String testString = "a\\,b\\\\,c,d\\\\\\,e,f\\\\g";
String[] splitedString = test.split(PATTERN_STRING);
for (String string : splitedString) {
System.out.println(string);
}
这里我有一个字符串,它将String字符串编码为String,其中转义字符为\且分隔符为,注意:(由于Java代码,示例中的反斜杠加倍)
反斜杠和逗号被转义在原始字符串中,结果字符串与逗号合并。我需要一个正则表达式将此字符串拆分为原始的字符串列表
因此,对于字符串
"a\,b\\,c,d\\\,e,f\\g"的示例,我需要获得这样的字符串:
"a\,b\\"
"c"
"d\\\,e"
"f\\g"
所以split的逻辑很简单:只有当前面的反斜杠数是偶数时才用分隔符逗号分隔:0,2,4 ......只有在这种情况下这个逗号是分隔符。如果逗号之前的反斜杠数是奇数,则转义为逗号,不应发生拆分。
对于这种情况,有人可以帮我使用适当的正则表达式吗?
编辑
我知道这个正则表达式:(?<!\\\\),
将有助于使用之前没有反斜杠的逗号分隔字符串。但在我的情况下,我需要拆分以防止逗号数为斜线之前的斜线。
感谢任何帮助。
答案 0 :(得分:1)
如果必须拆分,那么你可以试试像
这样的东西split("(?<!(?<!\\\\)\\\\(\\\\{2}){0,1000000000}),")
我使用了{0,1000000000}
而不是*
,因为Java中的后视需要有明显的最大长度,而1000000000
似乎已经足够好了,除非你有超过{{{ 1}}文字中的连续1000000000
。
如果它不是\\
,那么您可以使用
split
Matcher m = Pattern.compile("(\\G.*?(?<!\\\\)(\\\\{2})*)(,|(?<!\\G)$)",
Pattern.DOTALL).matcher(testString);
while (m.find()) {
System.out.println(m.group(1));
}
表示上一次匹配结束,或者如果这是Matcher的第一次迭代,并且字符串\\G
之前没有匹配开始。
但是实现速度最快且不那么热衷的是编写自己的解析器,它将使用^
之类的标志来表示当前检查的字符是使用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);
答案 1 :(得分:0)
尝试,
我只是通过使用字符串操作来实现你的逻辑。
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
答案 2 :(得分:0)
这将为您解决问题:
String[] splitedString = testString.split("(?<=[a-z])(\\\\{2})*,");
这里,它使用字符串中的\
的偶数(0是偶数),然后是,
用于分割分隔符。
使用lookbehind
,检查\
之前的最后一个字符是否为字母。