我有一个输入字符串,我需要在其上运行几个正则表达式模式(某种解析器)。运行这些正则表达式时,我只想考虑字符串的某个部分(从给定位置到结束)和我希望只有当输入的匹配在给定位置开始时才匹配模式。
我们假设输入字符串为abcdefghij
,当前位置为1
,并且我有这两种模式
[b-d]+
[h-j]+
鉴于我的排名是1
,我希望p1
匹配,我希望p2
不匹配(因为p2
匹配hij
部分输入 - 即:匹配从位置7
开始,而不是从位置1
开始。)
使用Matcher.find(offset)
不起作用,因为它不需要在给定位置开始匹配:
// Output: true (whereas I want it to be false)
System.out.println(Pattern.compile("[h-j]+").matcher("abcdefghij").find(1));
请注意,在我的模式中添加^
并不能解决问题:
// Output: false (whereas I want it to be true)
System.out.println(Pattern.compile("^[b-e]+").matcher("abcdefghij").find(1));
其他替代方案(不起作用):
(1)在我的输入字符串上应用.substring()
(并将^
添加到我的模式中)将起作用,但.substring()
的复杂性为O(n),这可能会有问题对我来说(这是一个库代码,将用于潜在的大型输入,这是我无法预先预测的方式)
(2)我可以使用matcher的对象.start()
方法来确定匹配发生的位置,如下所示:
matcher = Pattern.compile("[h-j]+").matcher("abcdefghij");
System.out.println(matcher.find(1) && matcher.start() == 1);
我的问题是regexp算法将在整个输入字符串中运行(可能很长),并且只有在找到匹配后matcher.start() == offset
条件才会拒绝匹配(如果它不是所需的)位置。似乎效率低下。
答案 0 :(得分:2)
使用Matcher.lookingAt()
锚定在开头而不是结尾(不像find
那样不锚定)。
具体做法是:
Matcher m = Pattern.compile(".....").matcher(input);
m.region(offset, input.length());
if (m.lookingAt()) {
...
}