我知道有很多其他类似的问题,但我已经建立了其他答案但没有成功。 我挖了here,here,here,here和here 但是这个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种其他排列。
答案 0 :(得分:1)
您的模式\*\*Header2\*\*\n[^*]+
不匹配,因为您的行**Header2**
在换行符之前包含尾随空格。添加*
就足够了,但我也在下面添加了其他选项。
\*{2}Header2\*{2} *\n([^*]+)
或者,您也可以使用以下正则表达式(这也允许您捕获包含*
的行,只要它们与标题^\*{2}[^*]*\*{2}
的格式不匹配 - 它也很漂亮从标题下的最后一个元素中删除空格 - 使用im
标志):
^\*{2}Header2\*{2} *\n((?:(?!^\*{2}[^*]*\*{2}).)*?)(?=\s*^\*{2}[^*]*\*{2}|\s*\Z)
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期望的结果。
\*\*
更改为\*{2}
:非常小的性能调整\n
更改为*\n
:在换行符之前考虑一行末尾的额外空格([^*]+)
:捕获OP期望进入捕获组1的内容答案 1 :(得分:0)
您可以使用
^\*\*Header2\*\*.*[\n\r]
(?P<content>(?:.+[\n\r])+)
使用multiline
和verbose
修饰符,请参阅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]+?)
(?=^\*\*)
答案 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']