Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java中的字符串中间开始ReGeXP匹配_Java_Regex - Fatal编程技术网

在java中的字符串中间开始ReGeXP匹配

在java中的字符串中间开始ReGeXP匹配,java,regex,Java,Regex,我正在使用regexps+一些手动解析在Java中解析一个相对复杂的表达式。我现在正在做的是从字符串中删除我已经解析过的内容,所以我接下来要在字符串的开头进行解析 我想更改它,因此我有一个int pos变量,并且不修改字符串。但是,模式和匹配器类似乎都没有标记要匹配的第一个字符的索引。有什么办法吗 (我知道我可以将str.substring(pos)传递给Matcher,但我想这会更昂贵,并且会使我的代码复杂一点,因为我经常使用start()和end()方法)。你的应用程序性能是否足够关键,st

我正在使用regexps+一些手动解析在Java中解析一个相对复杂的表达式。我现在正在做的是从字符串中删除我已经解析过的内容,所以我接下来要在字符串的开头进行解析

我想更改它,因此我有一个
int pos
变量,并且不修改字符串。但是,
模式
匹配器
类似乎都没有标记要匹配的第一个字符的索引。有什么办法吗


(我知道我可以将
str.substring(pos)
传递给
Matcher
,但我想这会更昂贵,并且会使我的代码复杂一点,因为我经常使用
start()
end()
方法)。

你的应用程序性能是否足够关键,str.substring(pos)是否重要?正则表达式将比子字符串慢多个数量级,因此与其使正则表达式更复杂,不如将其分解。这就是我的方法。

对你很有用

使用

javadoc说:

设置此匹配器区域的限制。区域是将被搜索以查找匹配项的输入序列的一部分。调用此方法将重置匹配器,然后将区域设置为从start参数指定的索引开始,到end参数指定的索引结束

A尝试在区域上查找匹配项,该区域默认为整个输入,但可以显式设置为特定子范围

从文件中:

匹配器在称为区域的输入子集中查找匹配项。默认情况下,区域包含匹配器的所有输入。区域可以通过方法修改,也可以通过和方法查询。区域边界与某些图案构造交互的方式可以更改。有关更多详细信息,请参阅和

请记住,与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()
        );
    }
以上打印内容():


关于锚定界和透明界 如前所述,指定区域时,可以根据需要更改某些模式构造的行为

锚定边界使区域的边界匹配各种(
^
$
等)

不透明边界本质上切断了lookaheads、lookbehinds和某些边界匹配构造的其余输入。另一方面,在透明模式下,他们可以根据需要看到区域外的字符


默认情况下,
Matcher
同时使用锚定边界和不透明边界。这适用于大多数子区域匹配场景,但您可以根据需要设置自己的组合。

字符串。子字符串是一个固定时间操作;字符数据不会被复制,而是与原始字符串共享。从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);
}
因此,就子字符串性能而言,无需担心任何问题。

该方法正是您所需要的。每次匹配某个对象时,都会将该区域的起始位置向上移动到该匹配结束的位置。就匹配器而言,这就是输入的开始

如果设置该选项,则可以将区域的开头视为文本的开头(即,
^
\A
将在此处匹配),如果设置,则向后看和单词边界仍可以“查看”前面的文本。您可以同时使用这两个选项


如果您总是希望下一个匹配精确地从区域的开始处开始,您甚至可以使用而不是--这是我发现的唯一一个适合该方法的用法。;)

这是
true
关于
substring
O(1)
时间和空间,但是索引需要重新编号以转换回全局索引,这是一个麻烦和容易出错的问题。谢谢,看起来这正是我需要的。我想在问之前我应该好好看看。naikus/Polygene的答案也很合适,但我不需要太多的控制。谢谢À注释如果有人有相同的问题:使用
find()
^
字符匹配整个字符串的开头,而不是搜索的开头。要确保匹配字符串的开头,请使用
region().lookingAt()
(解释如下)。
// 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);
}