Java \G如何在.split中工作?

Java \G如何在.split中工作?,java,regex,string,split,match,Java,Regex,String,Split,Match,我喜欢用Java打代码高尔夫(尽管Java太过冗长以至于没有竞争力),这是在尽可能少的字节内完成某种挑战。在我的一个答案中,我有以下代码: for(var p:"A4;B8;CU;EM;EW;E3;G6;G9;I1;L7;NZ;O0;R2;S5".split(";")) 在我们使用.split将2字符字符串转换为字符串数组后,它基本上在2字符字符串上循环。有人建议我将其改为此以节省4个字节: for(var p:"A4B8CUEMEWE3G6G9I1L7NZO0R2S5".split("(?&

我喜欢用Java打代码高尔夫(尽管Java太过冗长以至于没有竞争力),这是在尽可能少的字节内完成某种挑战。在我的一个答案中,我有以下代码:

for(var p:"A4;B8;CU;EM;EW;E3;G6;G9;I1;L7;NZ;O0;R2;S5".split(";"))
在我们使用
.split
将2字符字符串转换为字符串数组后,它基本上在2字符字符串上循环。有人建议我将其改为此以节省4个字节:

for(var p:"A4B8CUEMEWE3G6G9I1L7NZO0R2S5".split("(?<=\\G..)"))

但是
.split((?

如何分割(“(?首先,
\G
定义:它是一个锚,匹配字符串的开头或上一个匹配的结尾。它是一个位置。它既不消耗字符,也不改变光标位置。Alan Moore在之前的中写下了
\G
inside lookbehinds的这种行为是特定于引擎的。这将在Java b中以所需的长度拆分ut在PCRE中不会产生相同的结果


那么
\G
中的
\G
是如何在不完全正确的非匹配后停止的呢?
\G
是如何指示最后一次匹配结束的位置(或第一次运行的字符串的开始位置)可能解释了你想要什么。@KevinCruijssen问题是lookbehind案例中的
\G
属于“未定义”行为。这是一个“奇迹”,它在Java正则表达式中如此工作。因此,我不会依赖它,因为它看起来确实像一个bug(lookbehind是非消耗性的)这可以在任何未来的Java版本中修复。与Java lookbehinds中的
*
+
量词一样,无论Java正则表达式规范如何,量词都能起作用。@T.J.Crowder我没有深入研究代码,可能你是对的。但是,
split((?=\\G…))
应该是有效的,这又是一些Java的怪癖,与之相比,例如@T.J.Crowder,如果我知道的话。看,Python
re
根本不会在零长度匹配时分割,将
12345678
(?=\G..
分割为两个项目,
['','12345678']
,以与PHP相同的方式进行拆分。所有表明lookarounds中的
\G
行为的内容都是未定义的,每种语言都可以以自己的方式自由解释,我不依赖这些模式。我不反对使用它们,但我只是自己“知道我在做什么”。请检查-要点是带有
\G
的lookback实际上使用Java中的文本(或至少移动索引)(尽管它是非使用模式)@WiktorStribiżew-通读一遍,但没有发现它特别清晰。我很想看到你对这一点的解释的答案。毕竟你是大师。@WiktorStribiżew-带
\G
的lookback没有消耗任何文本。只是标记应该发生拆分的位置。是的,消耗是一个复杂的动作,
\G
这里就是我我喜欢这个索引。答案也很好!+1。不过我会在@T.J.Crowder的答案上留下被接受的分数,因为他更快。但是他和你的答案都很好,并且回答了我的两个问题。我很高兴。我没有回答更改接受分数的位置,只是想对这个问题多了解一些。
"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"]
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
 ↓A4
\G..↓B8
   \G..↓CU
      \G..
       .
       .
A   4   B  8
     \G .  . (?<=\G..)