Java字符串替换-非捕获组捕获

Java字符串替换-非捕获组捕获,java,regex,Java,Regex,我有以下Java代码: String initial = "Phone number: [194-582-9412]"; System.out.println(initial.replaceAll("\\d{3}\\-\\d{3}(?=\\-\\d{4})","XXX-XXX")); System.out.println(initial.replaceAll("\\d{3}\\-\\d{3}(?:\\-\\d{4})","XXX-XXX")); 它产生输出: 电话号码:[XXX-XXX-941

我有以下Java代码:

String initial = "Phone number: [194-582-9412]";
System.out.println(initial.replaceAll("\\d{3}\\-\\d{3}(?=\\-\\d{4})","XXX-XXX"));
System.out.println(initial.replaceAll("\\d{3}\\-\\d{3}(?:\\-\\d{4})","XXX-XXX"));
它产生输出:

电话号码:[XXX-XXX-9412]
电话号码:[XXX-XXX]


我的逻辑是找到3个数字,一个破折号,3个数字(捕捉到这一点),一个破折号和4个数字(不捕捉到这一点)。根据,以
?=
开头的先行组是非捕获组。根据,以
?:
开头的组也是非捕获组。我希望两个正则表达式产生相同的输出,
电话号码:[XXX-XXX-9412]
。但是,带有非捕获组
(?:\\-\\d{4}
的正则表达式似乎捕获并替换了整个电话号码。为什么会发生这种情况?

您可以使用捕获组来实际执行您想要的操作。在这里,它捕获要保留的部分并替换整个字符串。
$1
是对捕获组的反向引用

System.out.println(
首字母.replaceAll(\\d{3}-\\d{3}(\\-\\d{4})”,“XXX-XXX$1”);

我假设您已经意识到,如果
regex
不匹配,那么返回的原始字符串将不做任何更改

有什么理由不把电话号码作为一个组来记录吗?看起来像是双重否定(替换你不想要的,而不是抓住你所做的)Lookarounds不使用字符串中的字符。非捕获组使用字符串中的字符,但不创建捕获组。阅读并@Rogue I需要在向用户发送相关数据部分之前屏蔽电话号码(格式始终相同),前提是用户没有该信息的安全凭据。我只是想知道
?:
在这里的奇怪行为,因为这是我想到的第一个选项,但它没有按预期工作。@Thefourthbird好吧,我想我现在明白了。关于消费角色(而不是抓取群组)的一点对我很有帮助。它不是抓取。但是您正在替换所有匹配的内容,包括非捕获组。第一个成功的原因并不是因为它不能捕获,而是因为它的宽度为零。