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

问题描述 投票:1回答:3

我知道还有很多其他类似的问题,但我已经建立了其他答案但没有成功。我挖了hereherehereherehere,但是这个question最接近我正在尝试做的事情,但是它在php中我正在使用python3

我的目标是从正文中提取子字符串。正文格式化:

**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)

但那回归“无”。我试过的各种其他正则表达式也没有工作,或者抓得太多(所有剩余的标题)。为了它的价值,我也尝试过:\*\*Header2\*\*.+?^\**$ \*\*Header2\*\*[^*\s\S]+\*\*和其他大约10种其他排列。

python regex python-3.x search python-3.5
3个回答
1
投票

简要

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


See regex in use here

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

或者,您也可以使用以下正则表达式(这也允许您捕获带有*的行,只要它们与您的标题^\*{2}[^*]*\*{2}的格式不匹配 - 它也可以从标题下的最后一个元素中精美地删除空格 - 使用im标志):

See regex in use here

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

Usage

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. ([^*]+):捕获OP期望进入捕获组1的内容

0
投票

你可以用

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

使用multilineverbose修饰符,请参阅a demo on regex101.com。 之后,只需抓住content内部(即使用re.finditer())。


Broken down this says:
^\*\*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


In 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'))


I have the feeling that you even want to allow empty lines between paragraphs. If so, change the expression to
^\*\*Header2\*\*.*[\n\r]
(?P<content>[\s\S]+?)
(?=^\*\*)

另见a demo for the latter on regex101.com


0
投票

你可以试试这个:

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']
© www.soinside.com 2019 - 2024. All rights reserved.