如何使用 python 从降价 string/document 中提取“# Heading level 1”(header 及其段落)的文本?

How to extract text for "# Heading level 1" (header and its paragraphs) from markdown string/document with python?

我需要提取与传递给 python 函数的 header 级别 1 字符串匹配的文本(header 及其段落)。 在我工作的示例 mardown 文本下方:

# My first header

## Nec sic igni ad ad aventi

Lorem markdownum quantumque nunc, fine superi sagittis, haut regalis attollo,
ora inferius, mensor deam? Sedili quoque tauri. Quo limite ducem.

1. Arva fecit partes tosta
2. Insignia est ausae ut ut ait
3. O summa saepe

Sic ipsos, Phlegethontide nisi poterat neque quos tum partes rapitur. Filius
utraque: glande, ut exiles terram fiducia coeunt. Et caelo legit multis,
plangorem altoque; et iamque nec. Sanguine corpora prora quicquid insolida in
Parin: stupet est posses nos mater temptat, gemit num.

# My second header

## Primordia metuam his dixerat talaria cognoscenda

Lorem markdownum revulsum dilexit contra. Qui seu supplex Themis profuit quoque
Hyperionis, omnibus aesculus signa medendi. Aspiciunt rigidique finibus ducunt
postquam, huic postera lignum, properent.

- Nostro purgamina capitque longis
- Virtus suo moenibus
- Byblida longum pudibunda referre
- Via in ab vulneribus petita mirantur quamquam
- Et vela
- Nondum sacer meminisse Dircen novas dumque

例如我需要从上面的文本中提取header“我的第二个header”的所有文本。

我正在尝试使用正则表达式,但没有找到解决我问题的正确规则。

def findHeader("My second header")
r = re.compile(r"the regular expression")
    print(r.findall(text))

findHeader 输出:

# My second header

## Primordia metuam his dixerat talaria cognoscenda

Lorem markdownum revulsum dilexit contra. Qui seu supplex Themis profuit quoque
Hyperionis, omnibus aesculus signa medendi. Aspiciunt rigidique finibus ducunt
postquam, huic postera lignum, properent.

- Nostro purgamina capitque longis
- Virtus suo moenibus
- Byblida longum pudibunda referre
- Via in ab vulneribus petita mirantur quamquam
- Et vela
- Nondum sacer meminisse Dircen novas dumque

如果我没理解错的话,你是想在每一行的开头只捕获一个 # 符号。

帮助您解决问题的正则表达式是:r"(?:^|\s)(?:[#]\ )(.*\n+##\ ([^#]*\n)+)"。括号将捕获组或非捕获组隔离开来。第一组 (?:^|\s) 是非捕获组,因为它以问号开头。这里你希望你匹配的字符串以一行的开头或一个白色的space开头,那么在第二组中([#]\ )[#]将恰好匹配一个#字符。 \ 匹配 hash 和 h1 标签文本内容之间的 space。最后你想匹配任何可能的字符直到行尾,所以你使用特殊字符 .,它标识任何字符,后跟 + 将匹配前一个匹配字符的任何重复。

这可能是您正在寻找的代码片段,我使用您使用的相同示例测试对其进行了测试。

import re

text = """
# My first header

## Nec sic igni ad ad aventi

Lorem markdownum quantumque nunc, fine superi sagittis, haut regalis attollo,
ora inferius, mensor deam? Sedili quoque tauri. Quo limite ducem.

1. Arva fecit partes tosta
2. Insignia est ausae ut ut ait
3. O summa saepe

Sic ipsos, Phlegethontide nisi poterat neque quos tum partes rapitur. Filius
utraque: glande, ut exiles terram fiducia coeunt. Et caelo legit multis,
plangorem altoque; et iamque nec. Sanguine corpora prora quicquid insolida in
Parin: stupet est posses nos mater temptat, gemit num.

# My second header

## Primordia metuam his dixerat talaria cognoscenda

Lorem markdownum revulsum dilexit contra. Qui seu supplex Themis profuit quoque
Hyperionis, omnibus aesculus signa medendi. Aspiciunt rigidique finibus ducunt
postquam, huic postera lignum, properent.

- Nostro purgamina capitque longis
- Virtus suo moenibus
- Byblida longum pudibunda referre
- Via in ab vulneribus petita mirantur quamquam
- Et vela
- Nondum sacer meminisse Dircen novas dumque
"""

r = re.compile(r"r"(?:^|\s)(?:[#]\ )(.*\n+##\ ([^#]*\n)+)"")
print(r.findall(text))

如果你只想提取段落文本,那么你可以使用这个正则表达式:r"(?:^|\s)(?:[#]\ )(.+)",它与前一个类似,但它只是从捕获组中删除了#符号

这样就可以了:

import re

text = """
# My first header

## Nec sic igni ad ad aventi

Lorem markdownum quantumque nunc, fine superi sagittis, haut regalis attollo,
ora inferius, mensor deam? Sedili quoque tauri. Quo limite ducem.

1. Arva fecit partes tosta
2. Insignia est ausae ut ut ait
3. O summa saepe

Sic ipsos, Phlegethontide nisi poterat neque quos tum partes rapitur. Filius
utraque: glande.

# My second header

## Primordia metuam his dixerat talaria cognoscenda

Lorem markdownum revulsum dilexit contra. Qui seu supplex Themis profuit quoque
Hyperionis, omnibus aesculus signa medendi.

- Nostro purgamina capitque longis
- Virtus suo moenibus

# My third header

## Primordia metuam his dixerat talaria cognoscenda

Lorem markdownum revulsum dilexit contra. Qui seu supplex Themis profuit quoque
postquam, huic postera lignum, properent.

"""
def findHeader(search):
    r = re.compile(r"(?<!#)# " + search + r"(?s)(?:(?!(?<!#)# ).)+")
    return(r.findall(text))
    
print(findHeader("My second header"))

输出:

['# My second header\n\n## Primordia metuam his dixerat talaria cognoscenda\n\nLorem markdownum revulsum dilexit contra. Qui seu supplex Themis profuit quoque\nHyperionis, omnibus aesculus signa medendi.\n\n- Nostro purgamina capitque longis\n- Virtus suo moenibus\n\n']

解释:

r"          # raw string
    (?<!#)      # negative lookbehind, make sure we haven't a # before
    #           # a # and a space
"           # end string
+           # concat
    search      # header to be searched
+           # concat
r"          # raw string
    (?s)        # . matches newline
    (?:         # non capture group (Tempered greedy token)
        (?!         # negative lookahead, mmake sure we haven't after:
            (?<!#)      # negative lookbehind, make sure we haven't a # before
            #           # a # and a space
        )           # end lookahead
        .           # any character including newline
    )+          # end group, may appear 1 or more times
"           # end string