gpt4 book ai didi

java - 获得独特的正则表达式匹配器结果(不使用 map 或列表)

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:33:39 25 4
gpt4 key购买 nike

有没有办法只获得唯一的匹配项?匹配后不使用列表或映射,我希望匹配器输出立即是唯一的。

示例输入/输出:

String input = "This is a question from [userName] about finding unique regex matches for [inputString] without using any lists or maps. -[userName].";
Pattern pattern = Pattern.compile("\\[[^\\[\\]]*\\]");
Matcher matcher = pattern.matcher(rawText);
while (matcher.find()) {
String tokenName = matcher.group(0);
System.out.println(tokenName);
}

这将输出以下内容:

[userName]
[inputString]
[userName]

但我希望它输出以下内容:

[userName]
[inputString]

最佳答案

是的。您可以结合否定前瞻和反向引用:

"(\\[[^\\[\\]]*\\])(?!.*\\1)"

只有当与您的实际模式匹配的那个不再出现在字符串中时,它才会匹配。实际上,这意味着你总是得到每场比赛的最后出现,所以你会以不同的顺序得到它们:

[inputString]
[userName]

如果顺序对您来说是个问题(即,如果按第一次出现的顺序排序很重要),您将无法仅使用正则表达式来完成此操作。你需要一个可变长度的 look*behind* ,而这不受 Java 支持。

进一步阅读:


关于通用解决方案的一些说明

请注意,这将适用于任何匹配非零宽度的模式。一般的解决方案很简单:

(yourPatternHere)(?!.*\1)

(我省略了双反斜杠,因为它只适用于少数几种语言。)

如果您希望它使用具有零宽度匹配的模式(因为您只想知道一个位置并且只是出于某种原因使用环视),您可以这样做:

(zeroWidthPatternHere)(?!.+\1)

另外,请注意(通常)如果您的输入可能包含换行符,您可能必须使用“singleline”或“dotall”选项(否则前瞻将仅检查当前行)。如果您不能或不想激活它(因为您的模式包含不应匹配换行符的句点;或者因为您使用 JavaScript),这是通用解决方案:

(yourPatternHere)(?![\s\S]*\1)

为了使这个答案更广泛地适用,下面是如何只匹配每个匹配项的 第一次 出现(在具有可变长度 lookbehinds 的引擎中,如 .NET):

(yourPatternHere)(?<!\1.*\1)
or
(yourPatternHere)(?<!\1[\s\S]*\1)

关于java - 获得独特的正则表达式匹配器结果(不使用 map 或列表),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13613813/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com