我喜欢用 Java 进行代码高尔夫(尽管 Java 过于冗长而缺乏竞争力),即用尽可能少的字节完成某个挑战。在我的一个答案中,我有以下代码:
for(var p:"A4;B8;CU;EM;EW;E3;G6;G9;I1;L7;NZ;O0;R2;S5".split(";"))
在我们将 2 个字符的字符串转换为字符串数组后,它基本上会循环.split
。有人建议我可以用这个来节省 4 个字节:
for(var p:"A4B8CUEMEWE3G6G9I1L7NZO0R2S5".split("(?<=\\G..)"))
功能还是一样的。它循环遍历 2 个字符的字符串。
然而,我们都不能 100% 确定这是如何工作的,因此提出了这个问题。
我知道的:
I know .split("(?<= ... )")
用于分割,但保留尾部分隔符。
还有一种方法可以保留前导分隔符或分隔符作为分隔项:
"a;b;c;d".split("(?<=;)") // Results in ["a;", "b;", "c;", "d"]
"a;b;c;d".split("(?=;)") // Results in ["a", ";b", ";c", ";d"]
"a;b;c;d".split("((?<=;)|(?=;))") // Results in ["a", ";", "b", ";", "c", ";", "d"]
I know \G
is used to stop after a non-match is encountered.
EDIT: \G
is used to indicate the position where the last match ended (or the start of the string for the first run). Corrected definition thanks to @SebastianProske.
int count = 0;
java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("match,");
java.util.regex.Matcher matcher = pattern.matcher("match,match,match,blabla,match,match,");
while(matcher.find())
count++;
System.out.println(count); // Results in 5
count = 0;
pattern = java.util.regex.Pattern.compile("\\Gmatch,");
matcher = pattern.matcher("match,match,match,blabla,match,match,");
while(matcher.find())
count++;
System.out.println(count); // Results in 3
但如何.split("(?<=\\G..)")
使用时准确工作\G
分裂里面?
为什么会这样.split("(?=\\G..)")
不行?
这里有一个“在线尝试”链接,其中包含上述所有代码片段,以查看它们的实际效果。