正则表达式 – 懒惰量词{,}?不像我期望的那样工作
我有懒惰量词的问题.或者我很可能误解了我应该如何使用它们.
在Regex101上测试 .{1,5}匹配12345 {1,5}?比赛1 我对两场比赛都很好. .{1,5}?D匹配56789D !!我希望它能匹配9D 谢谢你澄清这一点. 解决方法
首先,请不要将正则表达式中的贪婪和懒惰视为获得最长/最短匹配的手段. “贪婪”和“懒惰”术语仅适用于模式可以匹配的最右边的字符,它对最左边的字符没有任何影响.当你使用延迟量词时,它将保证匹配的子串的结尾将是第一个找到的,而不是最后找到的(将用贪婪的量词返回).
正则表达式引擎从左到右分析字符串.因此,它搜索符合模式的第一个字符,然后,一旦找到匹配的子字符串,就会将其作为匹配项返回. 让我们看看它是如何解析字符串的.{1,5} D:1被发现并且D被测试.发现1之后没有D,正则表达式引擎扩展惰性量词并匹配12并尝试匹配D.在2之后有3,再次,引擎扩展懒点并执行5次.在扩展到最大值之后,它看到有12345并且下一个字符不是D.由于引擎达到最大限制量词值,匹配失败,测试下一个位置. 同样的情况发生在最多5个位置.当引擎达到5时,它会尝试匹配5D,失败,尝试56D,567D,5678D – 再次失败,当它尝试匹配56789D – 宾果! – 找到匹配. 这清楚地表明,模式开头的一个延迟量化的子模式默认情况下会“贪婪”,也就是说,它与最短的子字符串不匹配. 这是regex101.com的可视化: 现在,这是一个有趣的事实:.{1,5}?在模式的末尾将始终匹配1个字符(如果有的话)因为要求至少匹配1,并且返回有效匹配就足够了.所以,如果你写 有趣的事实2:在.NET中,您可以“请求”正则表达式引擎在RightToLeft修饰符的帮助下从右到左分析字符串.然后,使用.{1,5}?D,您将得到9D,见this demo. 有趣的事实3:在.NET中,(?< =(.{1,5}?))如果123456789D作为输入传递,D将把9捕获到组1中.这是因为lookbehind is implemented in .NET regex的方式(.NET反转字符串以及lookbehind内的模式,然后尝试匹配反向字符串上的单个模式).在Java中,5}))D(贪婪版本)将捕获9,因为它尝试范围内的所有可能的固定宽度模式,从最短到最长,直到一个成功. 一个解决方案是:如果你知道你需要1个字符后跟D,那就用吧 /.D/ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |