我正在使用regexps +一些手动解析在Java中解析一个相对复杂的表达式。我现在正在做的是删除我已经从字符串中解析的内容,所以我接下来要在字符串的开头解析。
我想改变这个,所以我有一个int pos
变量,我不修改字符串。但是,Pattern
和Matcher
类似乎都没有标记要匹配的第一个字符的索引。有没有办法做到这一点?
(我知道我可以将str.substring(pos)
传递给Matcher
,但我想它会更昂贵,并且会使我的代码复杂化,因为我正在使用start()
经常使用end()
种方法。
答案 0 :(得分:7)
java.util.regex.Matcher
尝试在区域上找到匹配项,默认为整个输入,但可以显式设置为特定的子范围。
来自文档:
匹配器在其输入的子集中找到称为 region 的匹配项。默认情况下,该区域包含所有匹配器的输入。可以通过
region(int start, int end)
方法修改该区域,并通过regionStart
和regionEnd
方法进行查询。可以更改区域边界与某些模式构造交互的方式。有关详细信息,请参阅useAnchoringBounds
和useTransparentBounds
。
请记住,与Java库类中的许多方法一样,start
索引是包含,但end
索引是独占。
以下是一个示例用法:
String text = "012 456 890 234";
Pattern ddd = Pattern.compile("\\d{3}");
Matcher m = ddd.matcher(text).region(3, 12);
while (m.find()) {
System.out.printf("[%s] [%d,%d)%n",
m.group(),
m.start(),
m.end()
);
}
以上打印(as seen on ideone.com):
[456] [4,7)
[890] [8,11)
如前所述,当您指定区域时,可以根据需要更改某些模式构造的行为。
锚定绑定使得该地区的边界与各种boundary matchers(^
,$
等匹配。
不透明边界基本上切断了前瞻,后瞻和某些边界匹配结构的其余输入。另一方面,在透明模式下,他们可以根据需要查看区域外的字符。
默认情况下,Matcher
同时使用锚定和不透明边界。这适用于大多数子区域匹配方案,但您可以根据需要设置自己的组合。
答案 1 :(得分:6)
答案 2 :(得分:1)
如何使用Matcher.region(int start, int end)
javadoc说:
设置此匹配器区域的限制。该区域是输入序列的一部分,将被搜索以查找匹配项。调用此方法会重置匹配器,然后将该区域设置为从start参数指定的索引处开始,并以end参数指定的索引结束。
答案 3 :(得分:1)
您正在寻找region()
方法。每次匹配时,都会将区域的起始位置移动到匹配结束的位置。就Matcher而言,现在是输入的开始。
如果您设置了useAnchoringBounds()
选项,则可以将区域的开头视为文本的开头(即^
或\A
将匹配),如果你设置useTransparentBounds()
,那么lookbehinds和单词边界仍然可以“看到”前面的文字。并且可以一次使用这两个选项。
如果您总是希望下一场比赛准确地从区域的开头开始,您甚至可以使用lookingAt()
代替find()
- 这是我用过的唯一一个很好用的方法。 ;)
答案 4 :(得分:0)
你的应用程序性能是否足够严重,str.substring(pos)是否重要?正则表达式将比子字符串慢几个数量级,因此不要让正则表达式更复杂,只需将其分解即可。那将是我的方法。
答案 5 :(得分:0)
String.substring
是一个恒定时间操作;字符数据不会被复制,而是与原始字符串共享。从JDK源代码:
// Package private constructor which shares value array for speed.
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}
public String substring(int beginIndex, int endIndex) {
// error checking omitted
return ((beginIndex == 0) && (endIndex == count)) ? this :
new String(offset + beginIndex, endIndex - beginIndex, value);
}
因此,在子串性能方面没有什么可担心的。