如何从字符串中的某个索引开始使用re.search?

Pin*_*ple 8 python regex

看起来像一个简单的事情,但我没有看到它.如何在字符串中间开始搜索?

aba*_*ert 9

re.search函数start不像str方法那样采用参数.但是search编译re.compile/ re.RegexObject模式的方法确实需要pos参数.

如果你考虑一下,这是有道理的.如果你真的需要反复使用相同的正则表达式,你可能应该编译它们.效率并不高 - 缓存可以很好地适用于大多数应用程序 - 但仅仅是为了提高可读性.


但是,如果您需要使用顶级函数,因为您无法出于某种原因预编译模式,该怎么办?

好吧,有很多第三方正则表达式库.其中一些包装PCRE或谷歌的RE2或ICU,一些从头开始实现正则表达式,它们都至少有一些略有不同,有时完全不同的API.

但是这个regex模块被设计成restdlib 的最终替代品(虽然现在因为它还没有准备就已经被碰了好几次)几乎可以作为替代品re和(以及其他扩展)的替代品它需要posendpos论证其search功能.


通常,你想要这样做的最常见的原因是"在我刚发现的那个之后找到下一个匹配",并且有一个更简单的方法:使用finditer而不是search.

例如,这个str方法循环:

i = 0
while True:
    i = s.find(sub, i)
    if i == -1:
        break
    do_stuff_with(s, i)
Run Code Online (Sandbox Code Playgroud)

...转换为这个更好的正则表达式循环:

for match in re.finditer(pattern, s):
    do_stuff_with(match)
Run Code Online (Sandbox Code Playgroud)

如果不合适,您可以随时切片:

match = re.search(pattern, s[index:])
Run Code Online (Sandbox Code Playgroud)

但这会使你的一半字符串的额外副本,这可能是一个问题,如果string实际上,例如,12GB mmap.(当然对于12GB的mmap情况,你可能想要映射一个新窗口......但是有些情况下也无济于事.)


最后,您始终可以修改模式以跳过index字符:

match = re.search('.{%d}%s' % (index, pattern), s)
Run Code Online (Sandbox Code Playgroud)

我在这里所做的就是添加,例如,添加.{20}到模式的开头,这意味着要匹配任何字符的20个,以及你想要匹配的任何其他内容.这是一个简单的例子:

.{3}(abc)
Run Code Online (Sandbox Code Playgroud)

正则表达式可视化

Debuggex演示

如果我给它abcdefabcdef,它将匹配'abc'第三个字符后面的第一个字符 - 即第二个字符abc.

但请注意它实际匹配的内容'defabc'.因为我正在使用捕获组来实现我的真实模式,并且我不会将它.{3}放在一个组中,match.group(1)所以它将完全按照我的要求工作,但match.group(0)会给我错误的东西.如果这很重要,你需要向后看.