【问题标题】:positive lookbehind not behaving correctly积极向后看行为不正确
【发布时间】:2019-10-03 19:16:56
【问题描述】:

正向回溯的代码 sn-p 如下

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 个位置都满足。

【问题讨论】:

  • 对于以数字 9 开头的字母,将正则表达式更改为 (?&lt;=9)[a-z] Demo
  • @Matt.G 感谢您的快速回复。我正在学习正则表达式,并且在这些lookarouds 中感到非常困惑。您能否指出任何显示正则表达式引擎如何运行的在线资源。以及为什么我对后视的理解是错误的
  • 错误:匹配一个字母(a-z)并往后(不是前面)寻找一个9,即如果前面找到的letter是9(匹配一个字母之后,pointer在那个字母之后,往后看会看pointer之前,也就是已经匹配的)

标签: java regex regex-lookarounds lookbehind


【解决方案1】:

问题

注意(?&lt;=9) 被放置在之后 [a-z]。这是什么意思?

让我们考虑像"a9c" 这样的数据。

在开始时,正则表达式引擎将它的“光标”放在它迭代的字符串的开头,这里:

|a9c
^-regex cursor is here

然后正则表达式引擎尝试匹配正则表达式模式的每个部分从左到右。因此,在[a-z](?&lt;=9) 的情况下,它首先会尝试为[a-z] 找到匹配项,在成功找到匹配项后,它将尝试转移到(?&lt;=9) 部分的评估。

所以[a-z] 的匹配将在这里发生:

a9c
*<-- match for `[a-z]`

匹配后正则表达式会将光标移至此处:

a|9c *^--- 正则表达式引擎光标 ^---- 匹配[a-z]

所以现在(?&lt;=9) 将被评估(注意光标| 的位置)。 (?&lt;=subregex) 检查光标之前是否存在可以被subregex 匹配的文本。但是在这里,因为光标直接在a 之后(?&lt;=9) 后视“看到”/包括a 作为子表达式应该测试的数据。但由于a 无法与9 匹配,因此评估失败。

解决方案

您可能想检查9 是否放置在 可接受的字母之前。为此,您可以通过多种方式修改您的正则表达式:

  • 使用[a-z](?&lt;=9.) 进行后视测试两个 前面的字符

    a9c|
     ^^
     9. - `9` matches 9, `.` matches any character (one directly before cursor)
    
  • 或更简单的(?&lt;=9)[a-z] 先查找9,然后查找[a-z],如果光标位于9|c,这将使正则表达式匹配9c

【讨论】:

【解决方案2】:

您当前的模式:[a-z](&lt;=9) 表示:匹配小写字母并确保该字母之后的 位置 前面是 9,这是矛盾的。

如果要匹配9 前面的字母,请使用:(&lt;=9)[a-z],这意味着:确保前面是9,如果是,则匹配小写字母。

【讨论】:

  • 您的回答对我帮助很大。我认为匹配 [a-z] 后光标没有移动.....
猜你喜欢
  • 2016-02-20
  • 2021-01-12
  • 2012-10-10
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多