积极的后视行为不正确
positive lookbehind not behaving correctly
正后视的代码片段如下
public class PositiveLookBehind {
public static void main(String[] args) {
String regex = "[a-z](?<=9)";
String input = "a9es m9x us9s w9es";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
System.out.println("===starting====");
while(matcher.find()) {
System.out.println("found:"+matcher.group()
+" start index:"+matcher.start()
+" end index is "+matcher.end());
}
System.out.println("===ending=====");
}
}
我原以为我应该有 4 个匹配项,但令我惊讶的是输出显示没有匹配项。
谁能指出我的错误?
据我了解,这里的正则表达式是字母表,前面是数字 9,在 4 个位置都满足。
您当前的模式:[a-z](<=9)
表示:匹配小写字母并确保 position 紧跟字母 9
,这是矛盾的.
如果要匹配以 9
开头的字母,请使用:(<=9)[a-z]
,这意味着:确保前面是 9
,如果是,则匹配小写字母。
问题
请注意 (?<=9)
位于 [a-z]
之后。这是什么意思?
让我们考虑 "a9c"
这样的数据。
在开始时正则表达式引擎将其 "cursor" 放在它迭代的字符串的开头,这里:
|a9c
^-regex cursor is here
然后正则表达式引擎试图匹配正则表达式模式的每个部分从左到右。因此,在 [a-z](?<=9)
的情况下,它首先会尝试为 [a-z]
找到匹配项,在成功找到它的匹配项后,它将尝试移动到 (?<=9)
部分的评估。
因此 [a-z]
的匹配将发生在这里:
a9c
*<-- match for `[a-z]`
匹配正则表达式后,光标将移至此处:
a|9c
*^--- 正则表达式引擎游标
^---- 匹配 [a-z]
所以现在 (?<=9)
将被评估(注意光标的位置 |
)。 (?<=subregex)
检查在光标之前是否存在可以被 subregex
匹配的文本。但是这里因为游标直接在 a
(?<=9)
之后,look-behind "sees"/includes that a
作为子表达式应该测试的数据。但由于 a
无法与 9
匹配,因此评估失败。
解决方案
您可能想检查 9
是否放在 之前 可接受的字母。为此,您可以通过多种方式修改正则表达式:
with [a-z](?<=9.)
你做回溯测试 两个 前面的字符
a9c|
^^
9. - `9` matches 9, `.` matches any character (one directly before cursor)
或更简单的 (?<=9)[a-z]
首先查找 9
然后查找 [a-z]
如果光标位于,这将使正则表达式匹配 9c
9|c
.
正后视的代码片段如下
public class PositiveLookBehind {
public static void main(String[] args) {
String regex = "[a-z](?<=9)";
String input = "a9es m9x us9s w9es";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
System.out.println("===starting====");
while(matcher.find()) {
System.out.println("found:"+matcher.group()
+" start index:"+matcher.start()
+" end index is "+matcher.end());
}
System.out.println("===ending=====");
}
}
我原以为我应该有 4 个匹配项,但令我惊讶的是输出显示没有匹配项。
谁能指出我的错误?
据我了解,这里的正则表达式是字母表,前面是数字 9,在 4 个位置都满足。
您当前的模式:[a-z](<=9)
表示:匹配小写字母并确保 position 紧跟字母 9
,这是矛盾的.
如果要匹配以 9
开头的字母,请使用:(<=9)[a-z]
,这意味着:确保前面是 9
,如果是,则匹配小写字母。
问题
请注意 (?<=9)
位于 [a-z]
之后。这是什么意思?
让我们考虑 "a9c"
这样的数据。
在开始时正则表达式引擎将其 "cursor" 放在它迭代的字符串的开头,这里:
|a9c
^-regex cursor is here
然后正则表达式引擎试图匹配正则表达式模式的每个部分从左到右。因此,在 [a-z](?<=9)
的情况下,它首先会尝试为 [a-z]
找到匹配项,在成功找到它的匹配项后,它将尝试移动到 (?<=9)
部分的评估。
因此 [a-z]
的匹配将发生在这里:
a9c
*<-- match for `[a-z]`
匹配正则表达式后,光标将移至此处:
a|9c
*^--- 正则表达式引擎游标
^---- 匹配 [a-z]
所以现在 (?<=9)
将被评估(注意光标的位置 |
)。 (?<=subregex)
检查在光标之前是否存在可以被 subregex
匹配的文本。但是这里因为游标直接在 a
(?<=9)
之后,look-behind "sees"/includes that a
作为子表达式应该测试的数据。但由于 a
无法与 9
匹配,因此评估失败。
解决方案
您可能想检查 9
是否放在 之前 可接受的字母。为此,您可以通过多种方式修改正则表达式:
with
[a-z](?<=9.)
你做回溯测试 两个 前面的字符a9c| ^^ 9. - `9` matches 9, `.` matches any character (one directly before cursor)
或更简单的
(?<=9)[a-z]
首先查找9
然后查找[a-z]
如果光标位于,这将使正则表达式匹配9c
9|c
.