如何避免Java正则表达式匹配中的隐式“^”和“$”?

时间:2009-03-02 23:18:07

标签: java regex

我一直在努力在Java 1.4.2中进行一些相对简单的正则表达式匹配。我对Perl的做事方式更加满意。这是正在发生的事情:

我正在尝试匹配/ ^< foo> /来自“< foo>< bar>”

我试试:

Pattern myPattern= Pattern.compile("^<foo>");
Matcher myMatcher= myPattern.matcher("<foo><bar>");
System.out.println(myMatcher.matches());

我得到“假”

我习惯说:

print "<foo><bar>" =~ /^<foo>/;

确实会返回true。

经过大量的搜索和实验,我发现 this说:

“String方法通过在模式之前放置一个不可见的^并在它之后放置$来进一步优化其搜索条件。”

当我尝试时:

Pattern myPattern= Pattern.compile("^<foo>.*");
Matcher myMatcher= myPattern.matcher("<foo><bar>");
System.out.println(myMatcher.matches());

然后返回预期的true。我不想要这种模式。终止。*不一定是必要的。

然后我发现了Matcher.useAnchoringBounds(boolean)方法。我认为明确告诉它不使用锚定边界会起作用。它没。我试过发一个

myMatcher.reset();

以防我在关闭属性后需要冲洗它。没运气。随后调用.matches()仍然返回false。

我忽略了什么?

编辑: 嗯,这很简单,谢谢。

3 个答案:

答案 0 :(得分:11)

使用匹配器find方法(而不是matches方法)

答案 1 :(得分:3)

在JDK1.5中添加了

Matcher.useAnchoringBounds(),所以如果你使用1.4,我不确定它是否会对你有所帮助,即使它确实有效(注意Javadocs中的@since 1.5)。 / p>

Matcher的Javadoc也声明the match() method

  

尝试将整个区域与模式匹配。

(强调我的)

这解释了为什么当您将模式更改为以.matches() == true结束时,您才获得.*

要匹配从头开始的区域,但不一定要求整个区域匹配,请使用find()lookingAt()方法。

答案 2 :(得分:3)

如果检查“匹配”,您希望找到输入字符串的哪一部分?

换句话说,

Matcher myMatcher= myPattern.matcher("<foo><bar>");
if (myMatcher.matches()) {
  System.out.println(myMatcher.group(0));
}

...应该打印什么?

如果您希望仅打印“<foo>”,请使用find()上的Matcher方法代替matches()。如果您确实希望在输入启动并找到“<foo>”时找到匹配项,那么您需要使用'^'明确指出。

如果您希望它与“<foo><bar>”匹配,则需要包含尾随的“.*”。