影刀RPA Excel文本函数实战:拆分、拼接、查找替换
作者:林焱
什么情况用什么
从网页采集的地址数据挤在一个单元格里需要拆分、多个字段需要拼成全名、产品名称里的关键词需要替换——这些文本处理在Excel里用LEFT、RIGHT、MID、FIND、SUBSTITUTE等函数能做,但批量处理几万行时Excel公式很慢且容易出错。在影刀RPA里用Python字符串方法或pandas矢量化操作,速度快且逻辑清晰。
适用场景:地址拆分、姓名拼接、产品编码提取、批量替换关键词、文本清洗标准化。
怎么做
文本拆分
importpandasaspd df=pd.read_excel(r"C:\Data\address.xlsx")# 按分隔符拆分(相当于Excel的"数据分列")# "广东省深圳市南山区科技园" → 省、市、区df['省']=df['地址'].str.extract(r'^(.+?省)')df['市']=df['地址'].str.extract(r'省(.+?市)')df['区']=df['地址'].str.extract(r'市(.+?[区县])')[video(video-c0sEXt0E-1783501706334)(type-csdn)(url-https://live.csdn.net/v/embed/525010)(image-https://v-blog.csdnimg.cn/asset/f4faa587144cb7070f19e8b36813806b/cover/Cover0.jpg)(title-店群矩阵自动化突破运营极限!)]# 按固定分隔符拆分成多列# "张三|13800138000|zhangsan@qq.com" → 姓名、手机、邮箱split_data=df['原始信息'].str.split('|',expand=True)df['姓名']=split_data[0]df['手机']=split_data[1]df['邮箱']=split_data[2]df.to_excel(r"C:\Data\address_split.xlsx",index=False)文本拼接
# 多列拼接成完整地址df['完整地址']=df['省']+df['市']+df['区']+df['详细地址']# 带分隔符拼接df['显示名']=df['姓名']+'('+df['部门']+')'# 条件拼接:有中间名才拼defbuild_full_name(row):parts=[row['姓']]ifpd.notna(row['中间名'])androw['中间名']:parts.append(row['中间名'])parts.append(row['名'])return''.join(parts)df['全名']=df.apply(build_full_name,axis=1)文本提取
# 从产品编码提取各部分信息# 编码格式:PRD-2026-001-REDdf['产品类别']=df['编码'].str.split('-').str[0]# PRDdf['年份']=df['编码'].str.split('-').str[1]# 2026df['序号']=df['编码'].str.split('-').str[2]# 001df['颜色']=df['编码'].str.split('-').str[3]# RED# 用正则提取手机号df['手机号']=df['备注'].str.extract(r'(1[3-9]\d{9})')# 用正则提取金额df['金额']=df['描述'].str.extract(r'(\d+\.?\d*)元').astype(float)# 提取括号内内容df['英文']=df['产品名'].str.extract(r'[((](.+?)[))]')文本查找与替换
# 替换(相当于SUBSTITUTE)df['产品名']=df['产品名'].str.replace('旧版','新版')df['地址']=df['地址'].str.replace('北京市','北京')# 直辖市简化# 批量替换多个关键词replacements={'有限公司':'有限公司','股份有限公司':'股份公司','集团':'集团',' ':' ',# 双空格变单空格' ':' ',# 全角空格变半角}forold,newinreplacements.items():df['公司名']=df['公司名'].str.replace(old,new)# 查找包含某关键词的行(相当于SEARCH/FIND)mask=df['产品名'].str.contains('手机',case=False,na=False)phone_products=df[mask]# 判断是否以某字符串开头mask_start=df['编码'].str.startswith('PRD')# 判断是否以某字符串结尾mask_end=df['文件名'].str.endswith('.pdf')文本截取
# LEFT:取前N个字符df['省简称']=df['省'].str[:2]# "广东省" → "广东"# RIGHT:取后N个字符df['文件后缀']=df['文件名'].str[-4:]# 取后4位# MID:从第N位开始取M个字符# Python从0开始,Excel从1开始df['月份']=df['日期'].str[5:7]# "2026-07-15" → "07"# 按字节截取(中文占2字节)defleft_by_bytes(text,byte_count):"""按字节截取文本"""ifpd.isna(text):return''text=str(text)result=''current_bytes=0forcharintext:char_bytes=2iford(char)>127else1ifcurrent_bytes+char_bytes>byte_count:breakresult+=char current_bytes+=char_bytesreturnresult df['简称']=df['公司名'].apply(lambdax:left_by_bytes(x,10))综合实战:清洗联系人数据
defclean_contact_data(input_path,output_path):"""清洗联系人数据"""df=pd.read_excel(input_path)# 1. 去除首尾空格text_cols=df.select_dtypes(include=['object']).columnsforcolintext_cols:df[col]=df[col].astype(str).str.strip()# 2. 全角转半角importunicodedataforcolintext_cols:df[col]=df[col].apply(lambdax:unicodedata.normalize('NFKC',x)ifx!='nan'else'')# 3. 手机号标准化df['手机号']=df['手机号'].str.replace(r'[^0-9]','',regex=True)# 只留数字df['手机号']=df['手机号'].str.extract(r'(1[3-9]\d{9})')# 提取有效手机号# 4. 邮箱标准化(转小写)df['邮箱']=df['邮箱'].str.lower()# 5. 姓名拆分df['姓']=df['姓名'].str[0]# 第一个字df['名']=df['姓名'].str[1:]# 剩余部分# 6. 地址拆分df['省']=df['地址'].str.extract(r'^(.+?[省市])')df['详细地址']=df['地址'].str.replace(r'^.+?[省市]','',regex=True)# 7. 空值处理df=df.replace('nan','')df=df.replace('None','')df.to_excel(output_path,index=False)returnoutput_path# 在影刀中调用clean_contact_data(r"C:\Data\contacts_raw.xlsx",r"C:\Data\contacts_clean.xlsx")有什么坑
坑1:str操作遇到None报错
列中有空值时,.str方法会报AttributeError:
# 问题:列中有None/NaNdf['结果']=df['文本'].str.replace('a','b')# NaN会变成NaN,不报错# 但链式操作可能出问题df['结果']=df['文本'].str.split('-').str[0]# NaN会变成None,str[0]报错# 解决:用na参数或fillnadf['结果']=df['文本'].fillna('').str.split('-').str[0]坑2:正则特殊字符未转义
替换文本中包含正则特殊字符(如.、*、+、?)时,会被当成正则语法:
temu店群自动化报活动案例
# 问题:要替换字符串"3.14"中的"."df['值']=df['值'].str.replace('.','-')# 把所有字符都替换了!# 解决:用regex=Falsedf['值']=df['值'].str.replace('.','-',regex=False)# 只替换字面的"."坑3:中文长度计算不一致
Python的len()按字符算,Excel的LEN按字节算,中文字符结果不同:
# Pythonlen('张三')# 结果:2(按字符)# Excel=LEN("张三")# 结果:4(按字节,GBK编码)# 如果需要和Excel一致deflen_by_bytes(text):"""按GBK字节计算长度"""returnlen(str(text).encode('gbk'))len_by_bytes('张三')# 结果:4坑4:split后列数不一致
不同行的分隔符数量不同,split后expand=True会产生不同列数,缺失列为NaN:
# "a|b|c" → 3列# "a|b" → 2列,第3列NaNsplit=df['信息'].str.split('|',expand=True)# 如果直接赋值可能列数对不上# 解决:指定列数split=df['信息'].str.split('|',expand=True,n=2)# 最多分3段# 或者只取前N列df['col1']=split[0]df['col2']=split[1]ifsplit.shape[1]>1else''坑5:contains匹配了意外内容
str.contains默认是正则匹配,某些特殊字符会引发误匹配:
# 问题:查找包含"C++"的行mask=df['技能'].str.contains('C++')# 报错!+是正则元字符# 解决:用regex=Falsemask=df['技能'].str.contains('C++',regex=False)# 或者转义importre mask=df['技能'].str.contains(re.escape('C++'))