Java - 解释这个正则表达式 (",(?=([^\"]*\"[^\"]*\")*[^\"]*$)", -1)

3

我正在将一个字符串 "foo,bar,c;qual="baz,blurb",d;junk="quux,syzygy"" 按逗号分隔,但想要保留引号内的逗号。这个问题在这个Java: splitting a comma-separated string but ignoring commas in quotes问题中得到了回答,但它没有完全解释作者是如何创建这段代码的,这段代码是:

line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)", -1);

好的,我理解了一些情况,但有一点让我感到困惑。我知道第一个逗号是用来匹配的。

然后

        (?= 

是一种正向搜索。

然后第一部分被分组。

  ([^\"]*\"[^\"]*\"). 

这是我感到困惑的地方。所以第一部分是……
  [^\"]* 

意味着以引号开头的任何行都会将标记分隔为零个或多个。

然后是 \". 现在这是像在字符串中打开引号还是表示匹配此引号?

然后它重复了完全相同的代码行,为什么?

      ([^\"]*\"[^\"]*\")

在第二部分,再次添加相同的代码以解释它必须以引号结束。
有人能解释一下我没有理解的部分吗?

1
方括号内的 ^ 表示非。反斜杠加双引号 \" 表示 ",但反斜杠是转义字符。因此,[^\"]* 匹配不包含 " 的任何字符串。 - M. Shaw
谢谢,如果我知道那部分的话会很有帮助。但是我仍然不理解 [^"] 后面的部分。 - spaga
@M.Shaw,它必须是[^\"]*匹配任何字符但不包括“`”,零或多次。 - Avinash Raj
[^\"] 表示任何不包含 " 的字符串。\" 匹配 "。因此,([^\"]*\"[^\"]*\") 匹配一个包含两个 " 并且最后一个字符是 " 的字符串。 - M. Shaw
@AvinashRaj 这基本上是任何不包含 " 的字符串。 - M. Shaw
1
一直以来都认为正则表达式只能写不能读……没有人能够读懂一个正则表达式,只能写它 ;) - Christian Kuetbach
3个回答

3

[^\"]代表不包含双引号的任意字符串。而\匹配双引号。因此,([^\"]*\"[^\"]*\")可以匹配包含两个"字符且最后一个字符为"的字符串。


1
我认为他们在回答后面的部分已经做得很好了: [^\"]表示匹配除引号外的任意字符。 \"表示引号。
因此,这部分([^\"]*\"[^\"]*\")是:
  1. [^\"]*表示匹配0个或多个除引号外的任意字符
  2. \"表示匹配引号,此处为开头引号
  3. [^\"]*表示匹配0个或多个除引号外的任意字符
  4. \"表示匹配引号,此处为结束引号
由于输入不是以引号开头,而是像a="abc",b="d,ef"的样例,因此只需要第一个[^\"]*。如果您要解析的是"abc","d,ef",则不需要它。

是的,这篇文章确实很好地解释了正在发生的事情,但我有点不在状态,所以并没有帮助到我。我只是真的不太理解语法。 - spaga

0

这是你的字符串 /,(?=([^\"]\"[^\"]\")[^\"]$)/

这是来自 https://regex101.com/ 的读数。

, matches the character , literally
(?=([^\"]*\"[^\"]*\")*[^\"]*$) Positive Lookahead - Assert that the regex below can be matched
1st Capturing group ([^\"]*\"[^\"]*\")*
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
Note: A repeated capturing group will only capture the last iteration. Put a capturing group around the repeated group to capture all iterations or use a non-capturing group instead if you're not interested in the data
[^\"]* match a single character not present in the list below
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
\" matches the character " literally
\" matches the character " literally
[^\"]* match a single character not present in the list below
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
\" matches the character " literally
\" matches the character " literally
[^\"]* match a single character not present in the list below
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
\" matches the character " literally
$ assert position at end of the string

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接