Python - 如何删除子字符串中的所有字符,包括关键字

Posted

技术标签:

【中文标题】Python - 如何删除子字符串中的所有字符,包括关键字【英文标题】:Python - How to delete all characters in a sub string up to and including a keyword 【发布时间】:2021-02-23 22:36:30 【问题描述】:

我在一列的数据框中有一个相当大的语料库(50 万篇新文章)。大多数(但不是全部)文章的开头都有各种随机丢弃的文字,直到短语“(路透社)-”

我尝试了以下正则表达式的各种排列,试图一次性调整整个列,但没有成功,因为它要么删除了文章的大块,要么什么都不做。

r = re.compile(r'\A\b.*[Reuters]\b')
reuters3 = reuters2['story_text'].str.replace(r,'', regex=True)

关于如何从正则表达式和熊猫方法的角度最好地解决这个问题有什么想法吗?谢谢你

下面提供的示例显示要在开头删除的文本的一般模式(直到并包括(路透社)-),以保持在中间摆脱并在最后摆脱(一切跟随并包括(编辑...)。确切的语言、字符和长度在这些关键切断词之外的文章中差异很大。

Chris Scicluna VALLETTA,1 月 1 日(路透社)- 周二午夜时分,地中海岛屿马耳他成为欧元区最小的成员......[多行文章文本]......公共信息活动取得了广泛认可的成功。 (Michael Winfrey 编辑)((gavin.jones@reuters.com;+39-06-8522-4232;路透社消息:gavin.jones.reuters.com@reuters.net))关键词:欧洲央行扩张/欧元马耳他

【问题讨论】:

【参考方案1】:

如果需要保留的话,可以使用

reuters2['story_text'].str.replace(r'(?s)^.*?(?=\(Reuters\)\s*-)', '')

如果你不需要需要保留这个词,你可以使用

reuters2['story_text'].str.replace(r'(?s)^.*?\(Reuters\)\s*-\s*', '')

或者,像这样使用Series.str.split

import pandas as pd
df = pd.DataFrame('story_text':['Some rubbish ... (Reuters) - Text'])
df['story_text'].str.split(r'\(Reuters\)\s*-', n=1).str[-1]
# => 0     Text

详情

(?s) - 使 . 匹配任何字符的 DOTALL 修饰符 ^ - 字符串的开头 .*? - 尽可能少的任何 0 个或更多字符 \(Reuters\) - 文字 (Reuters) 文本 (?=\(Reuters\)\s*-) - 与紧随其后的位置匹配的正向前瞻 (Reuters)、0+ 空格和 - \s*-\s* - - 包含 0+ 个空格。

请参阅regex demo #1 和regex demo #2。

split 解决方案使用更简单的正则表达式 \(Reuters\)\s*- 并将字符串拆分为 2 部分(因为定义了 n=1n 是拆分的数量),.str[-1] 得到最后一个(第二个)项目。

【讨论】:

您的两个解决方案都非常有效。谢谢!如果您要调整它以在文章末尾执行类似的任务,以切断 DF 中每篇文章尾随的不同随机文本 - 子字符串中的关键字是“(报告者” - 你会建议下面的代码吗? ? 对不起,我对此很陌生。df['story_text'].str.split(r'(Reporting)\s*-', n=1).str[1] @mickeymnemonic 应该是df['story_text'].str.split(r'\(Reporting\)\s*-', n=1).str[1] - 不要忘记在正则表达式模式中转义括号。 好的,非常感谢。超级超级有用!!! 西部最快的正则表达式!如果单列中有许多文本块,df.apply() 在这里也可能会有所帮助! wiktor,如果可以的话,我只是澄清一下。下面的代码不应该从每篇文章中删除尾随的随机文本/噪音吗?它本质上是在改编你给我的文章,以去除前面的文字/噪音。感谢您可以分享的任何观点。 reuters2['story_text'] = reuters2['story_text'].str.replace(r'(?s)\Z.*?(Edit', '') 语料库示例:[good text to keep ...] (Editing作者:Michael Winfrey) ((gavin.jones@reuters.com; +39-06-8522-4232; Reuters Messaging: gavin.jones.reuters.com@reuters.net)) 关键词:ECB EXPANSION/EURO MALTA [文章结尾]【参考方案2】:

只需.split()就可以了

parts = starting_string.split("Reuters", 1)  # split at most once
story = parts[-1]  # get the last part

例子

>>> s = "blah blah Reuters bulk of the story"
>>> s.split("Reuters", 1)
['blah blah ', ' bulk of the story']
>>> "missing the newsgroup!".split("Reuters", 1)
['missing the newsgroup!']
>>> ["start", "end"][-1]
'end'
>>> ["bulk without splitword"][-1]
'bulk without splitword'

在拆分目标周围添加空格或其他字符也可能会有所帮助

大家一起:

>>> s = "blah blah Reuters bulk of the story"
>>> s.split(" Reuters ", 1)[-1]
'bulk of the story'

您可能希望针对可能的情况进行一些额外的验证,即您的拆分字符串并未在标题中没有它的文章的某处简单地提及。也许简单地说,如果有两个部分,第二个比第一个长,最多 N 个字符。

【讨论】:

以上是关于Python - 如何删除子字符串中的所有字符,包括关键字的主要内容,如果未能解决你的问题,请参考以下文章

如何在Python中删除重复的子字符串

《Java》期末课程设计

如何在python中删除子字符串

如何从python中的unicode字符串中删除除数字和“,”之外的所有字符?

从Python中的字符串中删除所有非数字字符

我想从python中数据框列中的字符串链接中删除子字符串