正则表达式匹配以'-[`

时间:2018-07-06 19:08:26

标签: python regex string python-3.x substring

我有一个指定的主体块,其中包含GitHub Markdown列表,其格式如下:

**HEADERONE**
- [x] Logged In
- [ ] Logged Out
- [x] Spun Around
- [x] Did the hokey pokey

但是该列表周围有其他垃圾,例如:

A body paragraph about other things. Lorem ipsom and all that

**HEADERONE**
- [x] Logged In
- [ ] Logged Out
- [x] Spun Around
- [x] Did the hokey pokey

Maybe a link here www.go_ogle.com 

Another list that isn't important
- [ ] Thing one
- [ ] Thing two
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo  

我可以在抓取后以编程方式将字符串切碎,但是我很好奇是否有一种非常干净的方法来抓取我的列表吗?标头始终是相同的,因此从**HEADERONE**抓取直到双换行的第一个实例都可以正常工作。从**HEADERONE**抓到- [的最后一行结束,真是太棒了。

我正在使用

\*\*HEADERONE\*\*[^*]*?(?=\n{2})

但是在regex101中可以使用时,re.search("\*\*HEADERONE\*\*[^*]*?(?=\n{2})",body)由于某种原因未返回任何内容。 所以我切换到了

\*\*HEADERONE\*\*[\S\s]*?(?=\n{2})

但是,这太抢手了,包括第二个列表。有什么想法吗?

3 个答案:

答案 0 :(得分:3)

您可以找到\*\*HEADERONE\*\*到第一个空白行之间的所有内容,如下所示:

^(\*\*HEADERONE\*\*[\s\S]*?)^\s*$

Demo

[\s\S]*?匹配所有字符,包括换行符,直到第一行空白为止。如果有可能没有空行或字符串的末尾,则可以将该测试轻松添加到表单中:

^(\*\*HEADERONE\*\*[\s\S]*?)(?:^\s*$|\Z)

Demo


如果您想以Python非正则表达式的方式获取该块,并且这些块由两行或更多行分隔,则可以执行以下操作:

print('\n'.join(block for block in s.replace('\r\n', '\n').split('\n\n') if block.lstrip().startswith('**HEADERONE**')))

Try it online

或者,如果您有文件:

print('\n'.join(block for block in fo.read() if block.lstrip().startswith('**HEADERONE**')))

fo是在文件模式下以'U'打开的文件。

答案 1 :(得分:2)

regex = r'\*\*HEADERONE\*\*(?:\n.+)+'
#^^^ HEADER followed by ONE newline and some other stuff
results = re.findall(regex, text)
print(results[0])
#**HEADERONE**
#- [x] Logged In
#- [ ] Logged Out
#- [x] Spun Around
#- [x] Did the hokey pokey

答案 2 :(得分:2)

尽管将(?=\n{2})替换为(?=(?:\r\n){2})将解决此问题,因为输入中包含CRLF结尾,但我建议使用更精确的模式:

m = re.search(r'^\*\*HEADERONE\*\*(?:\r?\n-\s*\[[^][]*].*)*', s, re.M)
if m:
    print(m.group())

请参见regex demoPython demo

说明

  • ^-行的开头(re.M重新定义了^锚点行为)
  • \*\*HEADERONE\*\*-一个**HEADERONE**字符串
  • (?:\r?\n-\s*\[[^][]*].*)*-的零次或更多次连续重复
    • \r?\n-仅CRLF或LF结尾
    • --连字符
    • \s*-超过0个空格
    • \[-一个[字符
    • [^][]*-除][以外的0多个字符
    • ]-一个]
    • .*-该行的其余部分。

还有一种方法可以使用非正则表达式方法来捕获文件中的所有匹配项:

res = []
tmp = []
inblock = False
for line in f:  # f is a handle to the open file, or use s.splitlines() to split the string s into lines
    if line == '**HEADERONE**':
        tmp.append(line.rstrip())
        inblock = not inblock
    elif inblock and line.startswith("- ["):
        tmp.append(line.rstrip())
    else:
        if len(tmp) > 0:
            res.append("\n".join(tmp))
            tmp = []
            inblock = not inblock

请参见Python demo online。基本上,一旦找到**HEADERONE**,所有以- [开头的后续行都将附加到tmp,然后加入res列表中的项目中。