我目前正在为某些发票制作一个正则表达式生成器,我想知道是否有一种方法可以知道我的正则表达式仅与文本的一部分匹配。常规expr本身并不是很重要,我只想知道是否可以检查只有一场比赛而没有更多。
我当然使用Pattern
包中的Matcher
和java.util.regex
。
我尝试使用matcher.groupCount()
,但这似乎没用,因为它涉及组数而不是比赛数。
预先感谢您的回答。
答案 0 :(得分:0)
您可以在此处使用String#matches
并使用一些先行逻辑:
String input = "The quick brown fox jumps over the lazy dog.";
if (input.matches("((?!\\bfox\\b).)*\\bfox\\b(?!.*\\bfox\\b).*")) {
System.out.println("MATCH");
}
上面使用的正则表达式是(String#matches
使用隐式起始/结束锚点):
^((?!\bfox\b).)*\bfox\b(?!.*\bfox\b).*$
这将匹配fox
的第一次首次出现,但前提是fox
不会在输入字符串的其他位置出现。
编辑:
通过使用(?s)
标志启用全点模式,可以使以上答案适用于所有行:
String input = "The quick brown\nfox jumps \tover the lazy dog.";
if (input.matches("(?s)((?!\\bfox\\b).)*\\bfox\\b(?!.*\\bfox\\b).*")) {
System.out.println("MATCH");
}
答案 1 :(得分:0)
只需重复比赛并保持计数即可。
final Matcher matcher = Pattern.compile("[fm]oo").matcher(",foo,moo,");
int numMatches = 0;
String match = null;
while (matcher.find()) {
numMatches++;
match = matcher.group();
}
if (numMatches > 1) {
System.out.println("expected one match, found " + numMatches);
}
else {
System.out.println(match);
}
如果您不在乎有多少个匹配项,则可以在找到第二个匹配项后立即在循环中放置条件break
。
或重构为util方法。在此实现中,我想您可能不在乎有多少匹配项。
public static void main(String[] args) {
final Matcher matcher = Pattern.compile("[fm]oo").matcher(",foo,moo,");
System.out.println(
getSingleMatch(matcher)
.orElseThrow(() -> new RuntimeException("Expected exactly 1 match"))
//or handle the failure however use you like
);
}
private static Optional<String> getSingleMatch(Matcher matcher) {
final boolean foundOnce = matcher.find();
if (!foundOnce) return Optional.empty();
final String firstMatch = matcher.group();
final boolean foundTwice = matcher.find();
return !foundTwice ? Optional.ofNullable(firstMatch) : Optional.empty();
}