【问题标题】:Python returns no matches on working regexPython 在工作正则表达式上不返回匹配项
【发布时间】:2020-03-05 01:18:20
【问题描述】:

我在 python 中有一个字符串(不是原始的),类似于以下内容:

Plenary Papers (1)
Peer-reviewed Papers (113)
PLENARY MANUSCRIPTS (1)
First Author Index

Harrer
Plenary Papers

One Some title
John W. Doe
2018 Physics SOmething Proceedings
Full Text: Download PDF - PER-Central Record
Show Abstract - Show Citation
PEER REVIEWED MANUSCRIPTS (113)
First Author Index

Doe · Doe2 · Doe3 · Jonathan
Peer-reviewed Papers

Two some title
Alex White, Paul Klee, and Jacson Pollock
2018 Physics Research Conference Proceedings, doi:10.1234/perc.2018.pr.White
Full Text: Download PDF - PER-Central Record
Show Abstract - Show Citation

Tree Some title
Suzanne Heck, Alex Someone, John I. Smith, and Andrew Bourgogne
2018 Physics Education Research Conference Proceedings, doi:10.2345/perc.2018.pr.Heck
Full Text: Download PDF - PER-Central Record
Show Abstract - Show Citation

..

我想抓取这三篇论文的元数据,即每个标题后面的那几行(例如“One Some title”、“John W. Doe”和 2018 Physics Something Proceedings”)。

我想在选择的开始和结束时使用两种模式:

'r"\n\n"' 和 'r"Show Abstract - Show Citation"'。

这(几乎)适用于https://regex101.com/使用这个正则表达式:

\n\n(.*?)Show Abstract - Show Citation

一个小问题是它对前两篇论文很贪心。

但不是在 python 中:

    pattern=r"\n\n(.*?)Show Abstract - Show Citation"

    re.findall(pattern, titles) #titles is the text above

    #output is []
    pattern_only_one_line=r"\nShow Abstract - Show Citation"

    re.findall(pattern_only_one_line, titles)

    #output shows three lines

这可能是原始字符串的另一个问题吗?

【问题讨论】:

  • 您的正则表达式找不到匹配项 - regex101.com/r/X9AUw9/1
  • 可能是链接有问题。 regex101.com/r/iN6pX6/193 有效吗?
  • 您的正则表达式正在使用标志单行(点匹配换行符),因此您需要执行re.findall(pattern, titles, re.DOTALL)
  • @Wolph 是的,它正在工作!现在我想弄清楚如何在 .finditer 中使用它。如果需要,您可以添加答案

标签: python regex


【解决方案1】:

re.DOTALL 标志丢失。没有它 . 将无法匹配换行符。

但我们可以做得更好(当然取决于您的具体需求):https://regex101.com/r/iN6pX6/199

import re
import pprint

titles = '''
[Omitted for brevity]
..
'''

pattern = r'''
(?P<title>[^\n]+)\n
(?P<subtitle>[^\n]+)\n
((?P<etc>[^\n].*?)\n\n|\n)
'''

# Make sure we don't have any extraneous whitespace but add the separator
titles = titles.strip() + '\n\n'

for match in re.finditer(pattern, titles, re.DOTALL | re.VERBOSE):
    title = match.group('title')
    subtitle = match.group('subtitle')
    etc = match.group('etc')
    print('## %r' % title)
    print('# %r' % subtitle)
    if etc:
      print(etc)
    print()
    # pprint.pprint(match.groupdict())

【讨论】:

  • 我还在为 finditer 苦苦挣扎。使用简单的模式我无法得到结果。有了你的模式(我喜欢这个主意),我只答对了第三篇论文。
  • 我注意到我的代码块中仍然有你的模式,这可能就是杀死它的原因。试试新版本。你可以在这里看到结果:repl.it/repls/GentleGoldenBlocks
  • 差不多了:注意第二篇论文不正确:标题是“Doe·Doe2·Doe3·Jonathan”而不是“Two some title”,因为算法是贪婪的。知道如何解决这个问题吗?我试着用“。*?”四处寻找。但仍然无法正常工作
  • 抱歉回复慢。问题是它总是需要etc 部分。这似乎是可选的,所以我们必须让它成为可选的,看看更新:)
  • 谢谢,更新的代码没有解决我上面提到的问题,但我接受你的回答。我能够按照之前的建议使用 re.finditer(..., re.DOTALL) 提取我需要的内容
猜你喜欢
  • 1970-01-01
  • 2021-10-12
  • 2021-08-15
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
  • 2018-02-18
  • 2021-12-20
  • 1970-01-01
相关资源
最近更新 更多