【问题标题】:Extracting from a string before a specific pattern从特定模式之前的字符串中提取
【发布时间】:2019-04-28 15:51:15
【问题描述】:

我正在尝试删减德语维基百科文章,仅输出传记文本数据(删减所有文学作品、书单等)。因此,文本的示例可能如下所示:

一些相关文本 == Title1 == 更多相关文本 ===Title2=== 和 更相关的文字==一些关于人的文献==不需要的文字 ==作者的书==更多不需要的文字...

问题是在 ==[包括文学或书籍一词的文本]== 模式之前输出文本。应该是这样的:

一些相关文本 == Title1 == 更多相关文本 ===Title2=== 和 更相关的文字

我正在使用 Python 3,我尝试了一些像这样(以及更多)的正则表达式:

seperator = re.compile(r'={2,3}\s?.*literature.*\s?={2,3}')
m = seperator.search(text)
print (text[:m.start()])

但是,不幸的是,这只会输出文本直到第一个模式 == Title1 ==:

一些相关的文字

我怎样才能让它敏感地捕捉到第一个包含“文学”或“书籍”的模式?

我希望我能准确地描述问题。提前感谢您的帮助,如果之前有人问过这个问题,我很抱歉,我在任何地方都找不到解决方案。

顺便说一句,它无法区分 Title1 和 Title2,因为它们有时过于不同且不清楚,所以我试图区分清楚地标记传记文本结束的标题,例如文学或书籍。

【问题讨论】:

  • 'literature'这个词是否保证存在?
  • 如果您发布一个您尝试匹配的真实内容的示例,可能会更有帮助。甚至可能发布其中一篇文章的链接。如果您解释如何获取要解析的内容,它也可能会有所帮助。例如,如果您收到的原始内容是 html/xml/etc。为此使用解析器可能更容易。

标签: python regex


【解决方案1】:

这是一种纯 Python 方式。这会拆分 '=' 上的文本并检查每个拆分中的单词。如果找到匹配项,我们将打破循环并加入之前的所有内容:

s = 'some relevant text == Title1 == more relevant text ===Title2=== and more relevant text == some literature on person == unwanted text ==books by the author== more unwanted text'

lst = []
for x in s.split('='):
    if 'literature' in x:
        break
    else:
        lst.append(x)

print('='.join(lst).strip('='))
# some relevant text == Title1 == more relevant text ===Title2=== and more relevant text

【讨论】:

    【解决方案2】:

    如果我正确理解您的要求,以下正则表达式应该适合您:

    .+?(?=={2,3}[^=]*literature)
    

    Regex demo.

    Python 3 示例:

    import re
    
    regex = r".+?(?=={2,3}[^=]*literature)"
    test_str = "some relevant text == Title1 == more relevant text ===Title2=== and more relevant text == some literature on person == unwanted text ==books by the author== more unwanted text..."
    
    matches = re.finditer(regex, test_str, re.MULTILINE)
    for matchNum, match in enumerate(matches, start=1):
        print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))
    

    输出:

    在 0-87 找到匹配 1:一些相关文本 == Title1 == more 相关文字 ===Title2=== 和更多相关文字

    Python demo.

    【讨论】:

    • 非常感谢。这几乎看起来不错。但是当例如'literature'不是'== Title1 =='的一部分但是随后文本的一部分时,表达式会失败,例如'here is some text == Title1 == some more text withliterature.== Title2 与文献 =='。在这里,它会在 '== Title1' 之后立即剪切它,而不考虑以下文本并在 '==Title2 withliterature ==' 处剪切,假设的输出应该是:'here is some text == Title1 == some more text与文学'
    • 如果你只想在最新的“文献”之前剪切,那么让它变得贪婪(即,从上面的模式中删除?)。这是一个演示:regex101.com/r/3dVQiT/2
    • 抱歉回复晚了。再次感谢您的帮助。但是还是不行。我的问题不是在第一个或最新的“文献”之前剪掉它。它是在例如“==文学==”的第一次出现之前。正则表达式在等号之间寻找词文学(或其他词)是令人信服的。稍后我想在列表中添加其他词,不仅是文学,还有书籍,作者......等等。并找到“==文学或书籍或作者==”的第一个出现然后剪切之前的文本。希望澄清。
    • @MikeTwain 你没有在你的问题中说清楚,但无论如何,如果你想从 字符串的开头 匹配并在第一个 == 之前剪切后跟这些词中的任何一个,您都可以使用^.+?(?=={2,3}[^=]*(?:literature|books|author|whatever))。这是一个演示:regex101.com/r/0Jjfqt/1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    相关资源
    最近更新 更多