【问题标题】:Is there a way to manipulate numbered paragraphs in Python to remove certain paragraphs which do not fall in order?有没有办法在 Python 中操纵编号段落以删除某些不按顺序排列的段落?
【发布时间】:2021-12-01 15:06:48
【问题描述】:

我有一串文本,其中包含从“1”开始的编号段落。到“221.”,但是,有些段落不符合顺序,我想删除它们。以下是数据的外观:

text = """1. Shares of Paras Defence and Space Technologies gained 2.85 times. 
2. The company, engaged in manufacturing and testing of defence and space engineering products. 
"3. Its stock ended at Rs 499 versus issue price of Rs 175 per share.
42. On July 23, Zomato NSE 0.00 % Ltd. listed on the Indian stock exchanges.
43. That was exactly a week after the food-delivery and restaurant discovery platform's initial public offering went live. 
4. Paras Defence’s IPO, which closed on September 23, had generated bids worth Rs 38,021 crore. 
5. It surpassed the previous record of Salasar Technologies’ IPO. 
14. NBFCs are betting big time on the IPO. 
6. Paras Defence is one of the few players having an edge in defence deals."""

从上面的文本中,我想删除不按顺序的段落的内容,即。 “42.”、“43.”和“14”。

所需的输出:

relevant_text = '1. Shares of Paras Defence and Space Technologies gained 2.85 times. 
2. The company, engaged in manufacturing and testing of defence and space engineering products. 
3. Its stock ended at Rs 499 versus issue price of Rs 175 per share. 
4. Paras Defence’s IPO, which closed on September 23, had generated bids worth Rs 38,021 crore. 
5. It surpassed the previous record of Salasar Technologies’ IPO. 
6. Paras Defence is one of the few players having an edge in defence deals.'

我尝试匹配模式,但不知道如何继续。另外,我不确定正则表达式模式是否正确,因为它匹配 '1.'、'2.'等等,但不是“3.”。这是我想出的:

text_sequence = []

pattern = re.compile('(\s|["])[0-9]{1,3}\.\s')
matches = pattern.finditer(text)


for match in matches:
  for r in range(1, 999):
    if str(r) in match.group():
      text_sequence.append(match.span())
      text_sequence.append(match.group())

print(text_sequence)

有没有办法得到想要的输出?

P.S:我从这段代码中得到的匹配有重复的结果。

【问题讨论】:

    标签: python regex nlp


    【解决方案1】:

    如果你能用一个单一的模式匹配所有这些要点,比如

    (?s)((\d+)\. .*?)[^\w!?.…]*(?=\d+\. |\Z)
    

    (见this regex demo)和假设它们是按升序排列的,那么可以用

    import re
    pattern = r"((\d+)\. .*?)[^\w!?.…]*(?=\d+\. |\Z)"
    text = "1. Shares of Paras Defence and Space Technologies gained 2.85 times. 2. The company, engaged in manufacturing and testing of defence and space engineering products. \"3. Its stock ended at Rs 499 versus issue price of Rs 175 per share. 42. On July 23, Zomato NSE 0.00 % Ltd. listed on the Indian stock exchanges. 43. That was exactly a week after the food-delivery and restaurant discovery platform's initial public offering went live. 4. Paras Defence’s IPO, which closed on September 23, had generated bids worth Rs 38,021 crore. 5. It surpassed the previous record of Salasar Technologies’ IPO. 14. NBFCs are betting big time on the IPO. 6. Paras Defence is one of the few players having an edge in defence deals."
    result = []
    idx = 1
    for sent, num in re.findall(pattern, text, re.S):
        if int(num) == idx:
            result.append(sent)
            idx += 1
    
    print("\n".join(result))
    

    this Python demo。正则表达式匹配

    • ((\d+)\. .*?) - 第 1 组:
    • [^\w!?.…]* - 除单词和最后一句标点符号以外的任何零个或多个字符
    • (?=\d+\. |\Z) - 正向前瞻,需要字符串结尾 (\Z) 或 (|) 一位或多位数字

    输出:

    1. Shares of Paras Defence and Space Technologies gained 2.85 times.
    2. The company, engaged in manufacturing and testing of defence and space engineering products.
    3. Its stock ended at Rs 499 versus issue price of Rs 175 per share.
    4. Paras Defence’s IPO, which closed on September 23, had generated bids worth Rs 38,021 crore.
    5. It surpassed the previous record of Salasar Technologies’ IPO.
    6. Paras Defence is one of the few players having an edge in defence deals.
    

    注意:如果您首先按num 排序,则如果您有非升序的项目符号,则可以对此进行调整。

    【讨论】:

    • 仅供参考,可以使用for sent, num in sorted(re.findall(pattern, text, re.S), key=lambda x: int(x[1])): 进行排序,请参阅this demo
    • 这种方法肯定效果更好。我什至找到了一种跳过缺失项目符号的方法,该方法与此代码完美配合。
    • 当然。此代码不起作用的情况之一是使用这些要点:- ....'192.'、'193.'、'194'、'195.'、'196.'。它匹配的最后一个模式是“192.”。有解决方法吗? [P.S: 通过 idx+1 跳过丢失的匹配对此不起作用。]
    • @AshrayaSingh 我没有你的数据,所以我无法检查发生了什么。但是正则表达式需要在数字后加一个点。我没有看到194 后面的点。
    • 是的,这正是问题所在。没有“。”在子弹编号之后194. 另外,我犯了一个错误,最后匹配的项目符号是 no。 193.跨度>
    【解决方案2】:

    你可以这样做:

    text = """1. Shares of Paras Defence and Space Technologies gained 2.85 times. 
    2. The company, engaged in manufacturing and testing of defence and space engineering products. 
    3. Its stock ended at Rs 499 versus issue price of Rs 175 per share.
    42. On July 23, Zomato NSE 0.00 % Ltd. listed on the Indian stock exchanges.
    43. That was exactly a week after the food-delivery and restaurant discovery platform's initial public offering went live. 
    4. Paras Defence’s IPO, which closed on September 23, had generated bids worth Rs 38,021 crore. 
    5. It surpassed the previous record of Salasar Technologies’ IPO. 
    14. NBFCs are betting big time on the IPO. 
    6. Paras Defence is one of the few players having an edge in defence deals."""
    lines = text.split("\n")
    output = ""
    i = 0
    for l in lines:
        if (l.startswith("{}. ".format(i+1))):
            output+=l+"\n"
            i+=1
            
    print(output)
    

    如果你去掉第 3 行中多余的 "。如果你能保证后面跟着点的行号不在字符串中,你也可以考虑使用 "in" 而不是 "startswith"。

    【讨论】:

    • 由于某种原因这不起作用,它给出了一个空白字符串。这可能是因为字符串 'text' 没有换行符,因为我刚刚在此处添加了它们以提高可读性。
    • 这样就行了,代码在我的机器上运行,但我使用了换行符。
    • 是的,它适用于这个带有换行符的测试文本字符串,但不适用于原始字符串。有没有办法让这个工作没有字符串中固有的换行符?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-11
    • 1970-01-01
    相关资源
    最近更新 更多