有谁知道如何在考虑到其转义序列的情况下拆分字符上的字符串?
例如,如果字符是 ':',则“a:b”被分成两部分(“a”和“b”),而“a:b”根本不被分割。
我认为这很难(不可能?)与正则表达式有关。
先感谢您,
凯达
有谁知道如何在考虑到其转义序列的情况下拆分字符上的字符串?
例如,如果字符是 ':',则“a:b”被分成两部分(“a”和“b”),而“a:b”根本不被分割。
我认为这很难(不可能?)与正则表达式有关。
先感谢您,
凯达
由于 Java 支持可变长度的look-behinds(只要它们是有限的),您可以这样做:
import java.util.regex.*;
public class RegexTest {
public static void main(String[] argv) {
Pattern p = Pattern.compile("(?<=(?<!\\\\)(?:\\\\\\\\){0,10}):");
String text = "foo:bar\\:baz\\\\:qux\\\\\\:quux\\\\\\\\:corge";
String[] parts = p.split(text);
System.out.printf("Input string: %s\n", text);
for (int i = 0; i < parts.length; i++) {
System.out.printf("Part %d: %s\n", i+1, parts[i]);
}
}
}
(?<=(?<!\\)(?:\\\\){0,10})
在后面查找偶数个反斜杠(包括零个,最多 10 个)。输出:
Input string: foo:bar\:baz\\:qux\\\:quux\\\\:corge
Part 1: foo
Part 2: bar\:baz\\
Part 3: qux\\\:quux\\\\
Part 4: corge
另一种方法是匹配部分本身,而不是在分隔符处拆分。
Pattern p2 = Pattern.compile("(?<=\\A|\\G:)((?:\\\\.|[^:\\\\])*)");
List<String> parts2 = new LinkedList<String>();
Matcher m = p2.matcher(text);
while (m.find()) {
parts2.add(m.group(1));
}
奇怪的语法源于它需要处理字符串开头和结尾处的空片段的情况。当匹配恰好跨越零个字符时,下一次尝试将开始一个字符超过它的结尾。如果没有,它将匹配另一个空字符串,以及另一个,无穷无尽......
(?<=\A|\G:)
将在后面查找字符串的开头(第一段)或上一个匹配的结尾,然后是分隔符。如果我们这样做了(?:\A|\G:)
,如果第一部分为空(输入以分隔符开头),它将失败。\\.
匹配任何转义字符。[^:\\]
匹配任何不在转义序列中的字符(因为\\.
消耗了这两个字符)。((?:\\.|[^:\\])*)
捕获所有字符,直到第一个非转义分隔符进入捕获组 1。(?<=^|[^\\]):
让你接近,但不解决转义的斜杠。(这是一个文字正则表达式,当然您必须转义其中的斜杠才能将其转换为 java 字符串)
(?<=(^|[^\\])(\\\\)*):
那个怎么样?我认为这应该满足前面有偶数个斜杠的任何“:”。
编辑:不要投票。MizardX 的解决方案更好:)