经过几个小时的搜索,我决定问这个问题。为什么这个正则表达式不能^(dog).+?(cat)?
像我认为的那样工作(即捕获第一只狗和猫,如果有的话)?我在这里想念什么?
dog, cat
dog, dog, cat
dog, dog, dog
经过几个小时的搜索,我决定问这个问题。为什么这个正则表达式不能^(dog).+?(cat)?
像我认为的那样工作(即捕获第一只狗和猫,如果有的话)?我在这里想念什么?
dog, cat
dog, dog, cat
dog, dog, dog
cat
在不情愿地限定之后你没有得到可选的原因.+?
是它既是可选的又是非锚定的:引擎不会被迫进行匹配,因为它可以合法地将视为序列cat
的“尾部” 。.+?
如果你将 cat 锚定在字符串的末尾,即使用^(dog).+?(cat)?$
,你会得到一个匹配,但是:
Pattern p = Pattern.compile("^(dog).+?(cat)?$");
for (String s : new String[] {"dog, cat", "dog, dog, cat", "dog, dog, dog"}) {
Matcher m = p.matcher(s);
if (m.find()) {
System.out.println(m.group(1)+" "+m.group(2));
}
}
这打印(演示1)
dog cat
dog cat
dog null
万一猫后有事,你知道如何处理吗?
您可以通过构造一个匹配除 之外的任何内容的更复杂的表达式来处理它cat
,如下所示:
^(dog)(?:[^c]|c[^a]|ca[^t])+(cat)?
现在cat
可以在没有锚的情况下发生在字符串中的任何地方(演示 2)。
没有任何特定顺序,匹配此类模式的其他选项是:
对于非捕获组:
^(?:dog(?:, |$))+(?:cat)?$
或使用捕获组:
^(dog(?:, |$))+(cat)?$
环顾四周,
(?<=^|, )dog|cat(?=$|,)
有词界,
(?<=^|, )\b(?:dog|cat)\b(?=$|,)
如果我们在字符串中只有一个cat
而没有dog
,那么
^(?:dog(?:, |$))*(?:cat)?$
本来也是一种选择。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegularExpression{
public static void main(String[] args){
final String regex = "^(?:dog(?:, |$))*(?:cat)?$";
final String string = "cat\n"
+ "dog, cat\n"
+ "dog, dog, cat\n"
+ "dog, dog, dog\n"
+ "dog, dog, dog, cat\n"
+ "dog, dog, dog, dog, cat\n"
+ "dog, dog, dog, dog, dog\n"
+ "dog, dog, dog, dog, dog, cat\n"
+ "dog, dog, dog, dog, dog, dog, dog, cat\n"
+ "dog, dog, dog, dog, dog, dog, dog, dog, dog\n";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
}
}
Full match: cat
Full match: dog, cat
Full match: dog, dog, cat
Full match: dog, dog, dog
Full match: dog, dog, dog, cat
Full match: dog, dog, dog, dog, cat
Full match: dog, dog, dog, dog, dog
Full match: dog, dog, dog, dog, dog, cat
Full match: dog, dog, dog, dog, dog, dog, dog, cat
Full match: dog, dog, dog, dog, dog, dog, dog, dog, dog
如果您想简化/修改/探索表达式,它已在regex101.com的右上角面板中进行了说明。如果您愿意,您还可以在此链接中观看它如何与一些示例输入匹配。
jex.im可视化正则表达式:
@dasblinkenlight 的回答很好,但是当他/她被问到时,这是一个改进第二部分的正则表达式
万一猫后有事,你知道如何处理吗?
正则表达式^(dog)(.+(cat))?
将要求您捕获组号。3 而不是 2 来获得可选的猫,但在没有逐字符欺骗的情况下也能正常工作。
这是演示(再次,它是从@dasblinkenlight 的演示中分叉出来的,它允许我修补并找到这个解决方案,再次感谢!)