Regex \\ s * vs \\ s +在Lookbehind之后

时间:2017-09-12 20:58:34

标签: regex

是否有某些原因++在负面的背后是有效的,而* +则没有?

这是一个MCV示例:

select regexp_extract(
               'the hay   barn has cabins and hay.'
                , concat(
                '(?<!\\b(?:hay)\\b)'
                ,'\\s+'
                ,'('
                ,'\\b(?:antique|historic|bungalow|cabin|barn)\\b'
                ,')'
                ), 1),
                'the hay   barn has cabins and hay.'

出于某种原因,在这种情况下+正在工作,但*不是吗?

2 个答案:

答案 0 :(得分:1)

(?<!\b(?:hay)\b)\s*(\b(?:antique|historic|bungalow|cabin|barn)\b)模式与barn中的the hay barn has barns with cottages and hay匹配。

这是因为回溯所致。如果在当前位置之前有一个完整的单词(?<!\b(?:hay)\b),则hay lookbehind会使匹配失败,因此,跳过第一个hay之后的位置并且正则表达式引擎继续检查位置在空间之后。该位置左侧没有完整的单词hay,因此lookbehind返回 true 。然后,空格的数量可以为0(由于*),因此\s*成功,后续子图案的其余部分也是如此。

请注意,在量化的子模式之前使用lookbehind是没用的。您可以使用(?<!\bhay\s)(\b(?:antique|historic|bungalow|cabin|barn)\b)(请注意\s之后的非量化\bhay),但如果在预期匹配之前有2个或更多空格,则会失败。

更实际的解决方法是使用与hay上下文中所需单词匹配的正则表达式,并匹配并捕获所有其他上下文中的单词。像

这样的东西
\bhay\s*(?:antique|historic|bungalow|cabin|barn)\b|\b(antique|historic|bungalow|cabin|barn)\b

another regex demo。您需要的所有比赛都在第1组。

答案 1 :(得分:0)

所以解决这个问题的一个方法是在负面的后视镜中放置一个固定的宽度// s {0,x}。