正则表达式搜索到第一个实例 Python

Regex search up to first instance Python

知道还有很多其他类似的问题,但我已经建立了其他答案但没有成功。 我挖了 here, here, , here, and here 但是这个 最接近我想要做的,但是它在 php 中并且我正在使用 python3

我的目标是从 body 文本中提取子字符串。 body 的格式为:

**Header1**   
thing1  
thing2  
thing3  
thing4 

**Header2**  
dsfgs  
sdgsg  
rrrrrr 

**Hello Dolly**  
abider  
abcder  
ffffff

etc.

在 SO 上格式化很困难。但在实际文本中,没有空格,每行只有换行符。

我想要 Header2 下的内容,所以目前我有:

found = re.search("\*\*Header2\*\*\n[^*]+",body)
        if found:
            list = found.group(0)
            list = list[11:]
            list = list.split('\n')
            print(list)

但那是返回“None”。我尝试过的各种其他正则表达式也没有用,或者抓取太多(所有剩余的 headers)。 对于它的价值,我也尝试过: \*\*Header2\*\*.+?^\**$ \*\*Header2\*\*[^*\s\S]+\*\* 以及大约 10 个其他排列。

你可以使用

^\*\*Header2\*\*.*[\n\r]
(?P<content>(?:.+[\n\r])+)

使用 multilineverbose 修饰符,参见 a demo on regex101.com
之后,只需抓住 content 里面的东西(即使用 re.finditer())。


分解为:

^\*\*Header2\*\*.*[\n\r]    # match **Header2** at the start of the line 
                            # and newline characters
(?P<content>(?:.+[\n\r])+)  # afterwards match as many non-null lines as possible


Python:

import re
rx = re.compile(r'''
    ^\*\*Header2\*\*.*[\n\r]
    (?P<content>(?:.+[\n\r])+)
    ''', re.MULTILINE | re.VERBOSE)

for match in rx.finditer(your_string_here):
    print(match.group('content'))


我有一种感觉,你甚至想在段落之间留空行。如果是这样,将表达式更改为

^\*\*Header2\*\*.*[\n\r]
(?P<content>[\s\S]+?)
(?=^\*\*)

另见 a demo for the latter on regex101.com

你可以试试这个:

import re
s = """
**Header1**   
thing1  
thing2  
thing3  
thing4 

**Header2**  
dsfgs  
sdgsg  
rrrrrr 

**Hello Dolly**  
abider  
abcder  
ffffff
"""
new_contents = re.findall('(?<=\*\*Header2\*\*)[\n\sa-zA-Z0-9]+', s) 

输出:

['  \ndsfgs  \nsdgsg  \nrrrrrr \n\n'] 

如果你想从输出中删除特殊字符,你可以试试这个:

final_data = filter(None, re.split('\s+', re.sub('\n+', '', new_contents[0])))

输出:

['dsfgs', 'sdgsg', 'rrrrrr']

简介

您的模式 \*\*Header2\*\*\n[^*]+ 不匹配,因为您的行 **Header2** 在换行符之前包含尾随空格。添加 * 就足够了,但我还在下面添加了其他选项。


代码

See regex in use here

\*{2}Header2\*{2} *\n([^*]+)

或者,您也可以使用以下正则表达式(它还允许您捕获其中包含 * 的行,只要它们与您的 header ^\*{2}[^*]*\*{2} - 它还漂亮地从 header 下的最后一个元素中删除了空格 - 使用 im 标志):

See regex in use here

^\*{2}Header2\*{2} *\n((?:(?!^\*{2}[^*]*\*{2}).)*?)(?=\s*^\*{2}[^*]*\*{2}|\s*\Z)

用法

See code in use here

import re

regex = r"\*{2}Header2\*{2}\s*([^*]+)\s*"

test_str = ("**Header1**   \n"
    "thing1  \n"
    "thing2  \n"
    "thing3  \n"
    "thing4 \n\n"
    "**Header2**  \n"
    "dsfgs  \n"
    "sdgsg  \n"
    "rrrrrr \n\n"
    "**Hello Dolly**  \n"
    "abider  \n"
    "abcder  \n"
    "ffffff")

print(re.search(regex, test_str).group(1))

说明

该模式与 OP 的原始模式几乎相同。我做了一些小改动以使其性能更好并获得 OP 期望的结果。

  1. \*\* 更改为 \*{2}:非常小的性能调整
  2. \n 更改为 *\n:在换行符
  3. 之前考虑行尾的额外空格
  4. ([^*]+): 将 OP 期望的内容捕获到捕获组 1