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

时间:2017-12-28 17:25:26

标签: python regex python-3.x search python-3.5

知道有很多其他类似的问题,但我已经建立了其他答案但没有成功。 我挖了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种其他排列。

3 个答案:

答案 0 :(得分: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)

用法

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的内容

答案 1 :(得分:0)

您可以使用

^\*\*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

答案 2 :(得分: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']