首页 > 解决方案 > 为什么字符串替换函数不尊重单词边界 \b 正则表达式?

问题描述

我有这段代码可以删除给定数据系列中的所有 rt(或转推)。但是,这不起作用,因为我仍然到处都能看到 rt 。

def pre_process(text):

    newdataset['tidytext'] = newdataset['text'].str.lower()
    newdataset['tidytext'] = newdataset['tidytext'].str.replace(r'\brt\b', "")
    newdataset['tidytext'] = newdataset['tidytext'].replace(r'@\w+', '', regex=True)
    newdataset['tidytext'] = newdataset['tidytext'].replace(r'[!"#$%&()*+,-./:;<=>?@[\]^_`{|}~]', '', regex=True)

该函数的第二行是我发现问题最多的地方。

我试过:

newdataset['tidytext'] = newdataset['tidytext'].str.replace(r'rt', "")

但它删除了所有 rt,使 deport - depo 和 part - pa

非常感谢。

我有这个数据的示例截图:

在此处输入图像描述

对延迟上传示例文件表示歉意:https ://docs.google.com/spreadsheets/d/1CQm-fXdGGrCw6JJzbm9u1sgK4Nc6QTDIrWuiL2b2ZGI/edit?usp=sharing

正如您在文件中看到的,我选择了不同的模式,例如:

RT:
RT@
RT 
RT inside the sentence

我还确保有一些词,如deportpart、 a art icle 和其他词来正确地可视化我的问题。

非常感谢你。

标签: pythonregexpandas

解决方案


建议

1.) 像这样重写你的用户函数:

def pre_process(s):
    s = s.str.lower()
    s = s.str.replace(r'\brt\b', "")
    s = s.replace(r'@\w+', '', regex=True)
    s = s.replace(r'[!"#$%&()*+,-./:;<=>?@[\]^_`{|}~]', '', regex=True)

    return s

2.) 以您要处理的DataFrame系列作为参数对象调用用户函数:

newdataset['tidytext'] = pre_process(newdataset['text'])

回报:

ap my troops arrest ro suspects 6 buddhists killed httpapnewszqzoyhz 
my troops arrest ro suspects six buddhists killed accused httpnewspaperstread111326479 august 05 2017 at 0652pm ussupportll
my govnt probe finds no campaign of abuse against ro httpowlymdqb50dhfmk
my rejects allegations of human rights abuses against ro httpreutrs2wwuepg httptwittercomreutersstatus894153592306884608
this is part of a bigger problem we don’t need to deport them
north of ny is a good place to move into
this article is very sensationalist
you cant just  all of my tweetssome are part of a bigger storye18
calls for aearly morning prayer please 

证明

在查看了您的示例推文后,我认为问题在于您如何调用方法,而不是正则表达式的问题。

用户函数 中,引用数据帧系列上的操作pre_process(text)内部方法调用在用户函数的范围内。

用户功能是指您共享的代码:

def pre_process(text):

    newdataset['tidytext'] = newdataset['text'].str.lower()
    newdataset['tidytext'] = newdataset['tidytext'].str.replace(r'\brt\b', "")
    newdataset['tidytext'] = newdataset['tidytext'].replace(r'@\w+', '', regex=True)
    newdataset['tidytext'] = newdataset['tidytext'].replace(r'[!"#$%&()*+,-./:;<=>?@[\]^_`{|}~]', '', regex=True)

通过内部方法调用,我的意思是:

    newdataset['tidytext'] = newdataset['text'].str.lower()
    newdataset['tidytext'] = newdataset['tidytext'].str.replace(r'\brt\b', "")
    newdataset['tidytext'] = newdataset['tidytext'].replace(r'@\w+', '', regex=True)
    newdataset['tidytext'] = newdataset['tidytext'].replace(r'[!"#$%&()*+,-./:;<=>?@[\]^_`{|}~]', '', regex=True)

用户函数内执行的操作不会对用户函数之外的对象进行操作,因为您尚未将输入变量连接到内部操作。

解决此问题的一种方法是重写用户函数中的操作以作用于传递给用户函数的变量(如上面建议的那样):

def pre_process(s):
    s = s.str.lower()
    s = s.str.replace(r'\brt\b', "")
    s = s.replace(r'@\w+', '', regex=True)
    s = s.replace(r'[!"#$%&()*+,-./:;<=>?@[\]^_`{|}~]', '', regex=True)

    return s

使用这个用户函数,内部方法调用作用于变量s;所以当 DataFrame 系列对象传递给用户函数pre_process时,内部方法调用对其进行操作。

确保我们通过在用户函数中添加该行将对象传递回用户函数调用return s

现在我们可以为函数调用设置一个新列(即系列),以便创建已处理列的新列:

newdataset['tidytext'] = pre_process(newdataset['text'])

希望能帮助到你!


推荐阅读