0

我尝试使用useTransparentBounds(),但它似乎没有按预期工作(如ideone 所示)。在以下代码段中,我希望m.find()找到匹配项,因为启用了透明边界,因此允许在Matcher其区域边界之外进行搜索。为什么这不起作用?

import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Foo {
    public static void main(String[] args) {
        // match everything preceded by X
        Matcher m = Pattern.compile(".*(?<=X)").matcher("Foo BarX Baz");

        // limit matcher to first chars outside of normal lookahead scope
        m.region(0, 4);

        // matcher should still find a match because of transparent bounds
        m.useTransparentBounds(true);

        // this fails to find a match! why?
        System.out.println("found=" + m.find());
        System.out.println("result=" + m.group());
    }
}

(我在 Mac OSX Mountain Lion 上使用 J2SE 6 (1.6.0_37-b06-434-11M3909))

4

2 回答 2

1

首先,(?<=X)是向后看,而不是向前看;我想你的意思是.*(?=X)。现在让我们开始检查当您不限制匹配区域时会发生什么。

最初,.*使用整个字符串 ( "Foo BarX Baz"),然后将控制权交给(?=X)(前瞻),它断言下一个字符是X。那失败了(显然),所以匹配器返回最后一个字符并尝试消费 just "Foo BarX Ba",但他的前瞻再次失败。它继续这样,直到它达到它正在消耗的点"Foo Bar"。下一个字符是 now X,所以前瞻成功。

如果您将区域限制为(0,7)您可能希望它继续工作。 知道下一个字符是X,无论如何,您只是想查看,而X不是消费它。但是不,匹配器甚至看不到它。它的行为与您一开始就应用它时的行为完全相同"Foo Bar"。它不会费心查看 之后的字符r,因为它认为之后没有字符。

无论如何,这是默认行为。useTransparentBounds(true)为了匹配零宽度断言(环顾、字边界等),匹配器能够超越区域边界。你仍然不能消费任何不在当前区域的东西;那不是它的用途。

您的正则表达式不起作用的原因是因为它只查看字符串的前四个字符。要使前瞻成功,必须有一个X位于索引#4 的位置(例如"Foo X")。

于 2012-12-23T11:54:49.893 回答
0

这是因为您指定0-4的区域不是匹配的区域..

即应该是m.region(0,7);

它应该是0-7..这将匹配Foo BarX0-7 而不是0-4的范围内

但是你想匹配什么!你的正则表达式没有意义

于 2012-12-23T05:59:04.373 回答