为什么不在Matcher的区域外使用TransparentBounds()搜索?

时间:2012-12-23 05:39:50

标签: java regex

我尝试使用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))

2 个答案:

答案 0 :(得分:1)

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

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

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

无论如何,这是默认行为。 useTransparentBounds(true)所做的是使匹配器能够超出区域的界限,以便匹配零宽度断言(外观,字边界等)。你仍然不能消费任何不在当前区域的东西;这不是它的用途。

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

答案 1 :(得分:0)

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

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

应为0-7 ..这将匹配{0} 0-4

范围内的Foo BarX

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