首页 > 解决方案 > 仅删除列表中出现的第一个实例

问题描述

我有一个数据框,在名为“original_column”的第一列中有文本。

我已经成功地从带有列表的文本列“original_column”中挑选出特定的单词,并将它们附加到另一列并使用以下代码从原始列中删除:

list1 = {’text’ , ‘and’ , ‘example’}

finder = lambda x: next(iter([y for y in x.split() if y in list1]), None)

df['list1'] = df.original_column.apply(finder)

df['original column']=df['original column'].replace(regex=r'(?i)'+ df['list1'],value="")

现在,我希望在将列出的单词附加到新列之后,仅从“original_column”中删除列表中特定单词的第一个实例,从而构建此代码。

数据框当前如下所示:

|   original column  |
__________________________
|   text text word   | 
--------------------------
|    and other and   | 

我当前的代码输出这个:

|   original column   | list1
______________________________
|        word         | text
------------------------------
|        other        |  and

我希望输出这个:

|   original column   | list1
_______________________________
|      text word      | text
-------------------------------
|      other and      |  and

标签: pythonregexlistdataframetext

解决方案


要匹配第一个模式出现并删除它而不删除第一次出现之前的文本,您可以使用

^(.*?)模式

并将其替换为对捕获组值的反向引用,此处为\1.

您可以将list1列表中的任何单词匹配为整个单词(使用\b(?:word1|word2|wordN)\b类似模式),并使用(?s)^(.*?)匹配字符串开头的任何字符的最少数量的模式捕获它之前的所有文本。

采用

df['original column'] = df['original column'].str.replace(rf"(?s)^(.*?)\b(?:{'|'.join(list1)})\b", r"\1").str.strip()

使用的正则表达式是

(?s)^(.*?)\b(?:text|and|example)\b

请参阅正则表达式演示

细节

  • (?s)-re.DOTALL允许.匹配任何字符,包括换行字符
  • ^- 字符串的开始
  • (.*?)- 第 1 组:任意 0 个或更多字符,尽可能少
  • \b(?:text|and|example)\b- 字母数字单词列表中的一个完整单词(也可能包含一个 undersocre)

替换是\1,对使用第一个(也是唯一的)捕获组捕获的值的反向引用。


推荐阅读