处理字符串时,常常遇到在给定字符串中查找指定子字符串,或者找到以后用另外的字符串进行替换的任务。本节介绍进行字符串查找和替换的方法。
字符串的查找
【Excel VBA】
Excel VBA中用InStr函数返回一个字符串在另一个字符串中首次出现的位置。该函数的语法格式为:
InStr([Start,]String1,String2[,Compare])
其中,Start为可选参数,表示查找的起点,不设置时从字符串的第1个字符处开始查找。String1为原始字符串,判断String2表示的字符串在String1中首次出现的位置。Compare参数表示字符串匹配的方式,默认值为vbBinaryCompare,区分大小写;设置为vbTextCompre时不区分大小写。
下面给定两个字符串,判断第2个字符串在第1个字符串中首次出现的位置。示例文件的存放路径为Samples\ch06\Excel VBA\查找和替换.xlsm。
Sub Test()
Dim strA As String
Dim strB As String
Dim intP As Integer
strA = "Hello VBA"
strB = "VB"
intP = InStr(strA, strB)
Debug.Print intP
End Sub
运行程序,在立即窗口中输出7,表示strB在strA中首次出现的位置为第7个字符处。
使用InStrRev函数可以反向查找,即从字符串末尾向前查找。该函数的语法格式为:
InStrRev(String1,String2[Start,] [,Compare])
各参数的意义与InStr函数的相同。
【Python】
使用字符串的find方法和rfind方法返回一个字符串在另一个字符串中首次出现的位置和最后出现的位置。
下面返回字符串'Py'在字符串'HePyllo Python'中首次和末次出现的位置。注意位置的基数为0。
>>> 'HePyllo Python'.find('Py')
2
>>> 'HePyllo Python'.rfind('Py')
8
用字符串的count方法返回指定字符串在另一个字符串中出现的次数。例如计算字母a在字符串'abca'中出现的次数:
>>> 'HePyllo Python'.count('Py')
2
用字符串的startswith方法判断字符串是否以指定字符串打头,如果是,返回True,否则返回False。
>>> 'abcab'.startswith('abc')
True
用字符串的endswith方法判断字符串是否以指定字符串结尾,如果是,返回True,否则返回False。
>>> 'abcab'.endswith('ab')
True
字符串的替换
【Excel VBA】
使用Replace函数替换指定字符串中的某子字符串。该函数的语法格式为:
strR=Replace(Expression,Find,Replace[Start[,Count[,Compare]]])
其中,Expression为给定的原始字符串,Find为被替换的子字符串,Replace为用作替换的子字符串,Count表示替换次数,其他参数的意义跟InStr函数的相同。函数返回替换后的字符串strR。
下面给定一个字符串,用"Python"替换其中的"VBA"。示例文件的存放路径为Samples\ch06\Excel VBA\查找和替换.xlsm。
Sub Test2()
Dim strA As String
Dim strC As String
strA = "Hello VBA"
strB = "VB"
strC = Replace(strA, "vBa", "Python") '区分大小写
Debug.Print strC
strC = Replace(strA, "vBa", "Python", , , vbTextCompare) '不区分大小写
Debug.Print strC
End Sub
运行程序,立即窗口中输出两次替换的结果:
Hello VBA
Hello Python
第1次替换,因为区分大小写,"VBA"和"vBa"不同,不进行替换;第2次替换时指定Compare参数的值为vbTextCompare,不区分大小写,"VBA"和"vBa"表示相同的字符串,进行替换。
【Python】
使用字符串的replace方法,用指定字符串替换给定字符串中的某个子字符串。该方法的语法格式为:
str.replace(str1,str2,num)
其中,str为给定的字符串,参数str1为给定字符串中被替换的子字符串,参数str2为用作替换的字符串,参数num指定替换不能超过的次数。当忽略num参数或指定num参数的值为-1时能替换的全部替换。
下面将给定字符串中的字母a替换为w,替换次数不能超过5次。
>>> 'abcababcababcab'.replace('a','w',5)
'wbcwbwbcwbwbcab '
>>> 'abcababcababcab'.replace('a','w')
'wbcwbwbcwbwbcwb'
字符串的查找和替换示例-提取省市县
图6-6所示工作表中,第1列数据表示某些地区的省市县3级行政单位,现在要求将这3级行政单位分别提取出来并显示在第2-4列。
图6-6 提取省市县
提取的思路是查找行政单位关键字省、自治区、市、自治州、县和区等在字符串中的位置,从而计算出各级行政单位对应的名称并输出到指定单元格。
【Excel VBA】
遍历第1列各行数据,使用Instr函数查找各关键字在字符串中的位置并计算得到各级行政单位对应的名称,输出结果到第2-4列。示例文件的存放路径为Samples\ch06\Excel VBA\提取省市县.xlsm。
Sub Test()
Dim intI As Integer
Dim intR As Integer
Dim sht As Object
Set sht = ActiveSheet
Dim strAdr As String '详细文本
Dim intA As Integer, intB As Integer '省(自治区)出现的位置
Dim intC As Integer, intD As Integer '市(自治州)出现的位置
Dim strA As String '省(自治区)
Dim strB As String '市(自治州)
Dim strC As String '县(区)
'数据行数
intR = sht.Range("A2").End(xlDown).Row
'遍历各行数据
For intI = 2 To intR
strAdr = sht.Cells(intI, 1).Value
'获取省(自治区)名称
intA = InStr(strAdr, "省")
If intA <> 0 Then
strA = Left(strAdr, intA)
End If
intB = InStr(strAdr, "自治区")
If intB <> 0 Then
strA = Left(strAdr, intB + 2)
End If
'获取市(自治州)名称
intC = InStr(strAdr, "市")
If intC <> 0 Then
If InStr(strAdr, "自治区") <> 0 Then
strB = Mid(strAdr, intB + 3, intC - intB + 2)
Else
strB = Mid(strAdr, intA + 1, intC - intA)
End If
End If
intD = InStr(strAdr, "自治州")
If intD <> 0 Then
If InStr(strAdr, "自治区") <> 0 Then
strB = Mid(strAdr, intB + 3, intD - intB)
Else
strB = Mid(strAdr, intA + 1, intD - intA + 2)
End If
End If
'获取县(区)名称
If InStr(strAdr, "自治州") <> 0 Then
strC = Right(strAdr, Len(strAdr) - intD - 2)
Else
strC = Right(strAdr, Len(strAdr) - intC)
End If
'输出
sht.Cells(intI, 2).Value = strA
sht.Cells(intI, 3).Value = strB
sht.Cells(intI, 4).Value = strC
Next
End Sub
运行程序,在工作表中第2-4列输出结果,如图6-6中所示。
【Python】
遍历第1列各行数据,使用字符串的find方法查找各关键字在字符串中的位置并计算得到各级行政单位对应的名称,输出结果到第2-4列。本示例的数据文件存放路径为Samples\ch06\Python\提取省市县.xlsx,py文件保存在相同目录下,文件名为sam06-06.py。
import xlwings as xw #导入xlwings包
#从constants类中导入Direction
from xlwings.constants import Direction
import os #导入os包
#获取本py文件的当前路径
root = os.getcwd()
#创建Excel应用,可见,没有工作簿
app=xw.App(visible=True, add_book=False)
#打开数据文件,可写
bk=app.books.open(fullname=root+\
r'\提取省市县.xlsx',read_only=False)
sht=bk.sheets(1) #获取第1个工作表
#工作表中第1列数据最大行号
rows=sht.api.Range('A2').End(Direction.xlDown).Row
n=1 #记录当前行号
#遍历数据区域的单元格
for rng in sht.range('A2:A'+str(rows)):
n+=1 #行号加1
addr=rng.value #当前单元格中的字符串
#获取省(自治区)名称
ad1=addr.find('省') #第1次出现省字的位置,基数为0
if ad1!=-1:str1=addr[:ad1+1] #如果找到了,获取省份字段
ad2=addr.find('自治区') #自治区的情况
if ad2!=-1:str1=addr[:ad2+3] #类似判断和处理
#获取市(自治州)名称
ad3=addr.find('市') #第1次出现市字的位置
if ad3!=-1: #如果找到了
if ad2!=-1: #前面如果是自治区
str2=addr[ad2+3:ad3+3] #获取市的字段
else: #前面如果是省
str2=addr[ad1+1:ad3+1] #获取市的字段
ad4=addr.find('自治州') #第1次出现自治州的位置
if ad4!=-1: #如果找到了
if ad2!=-1: #如果前面是自治区
str2=addr[ad2+3:ad4+3]
else: #前面如果是省
str2=addr[ad1+1:ad4+3]
#获取县(区)名称
if ad4!=-1: #如果前面是自治州
str3=addr[ad4+3:]
elif ad3!=-1: #如果前面是市
str3=addr[ad3+1:]
#输出
sht.cells(n,2).value=str1
sht.cells(n,3).value=str2
sht.cells(n,4).value=str3
运行脚本,在工作表中第2-4列输出结果,如图6-6中所示。
字符串的查找和替换示例-统一列数据的单位
图6-7上表中,第2列采购明细中各食材的重量单位不统一,有公斤、kg和千克等。现在希望将各单位统一为公斤。
图6-7 统一列数据的单位
【Excel VBA】
遍历第2列各行数据,用Replace方法将重量单位kg和千克替换为公斤。示例文件的存放路径为Samples\ch06\Excel VBA\统一列数据的单位.xlsm。
Sub Test()
Dim intI As Integer
Dim intR As Integer
Dim strT As String
'数据行数
intR = ActiveSheet.Range("A1").End(xlDown).Row
'遍历第2列数据
For intI = 2 To intR
'将kg和千克替换为公斤
strT = ActiveSheet.Cells(intI, 2).Value
strT = Replace(strT, "kg", "公斤")
strT = Replace(strT, "千克", "公斤")
ActiveSheet.Cells(intI, 2).Value = strT
Next
End Sub
运行程序,替换结果如图6-7中下表所示。
【Python】
遍历第2列各行数据,用字符串的replace方法将重量单位kg和千克替换为公斤。本示例的数据文件存放路径为Samples\ch06\Python\统一列数据的单位.xlsx,py文件保存在相同目录下,文件名为sam06-07.py。
import xlwings as xw #导入xlwings包
#从constants类中导入Direction
from xlwings.constants import Direction
import os #导入os包
#获取本py文件的当前路径
root = os.getcwd()
#创建Excel应用,可见,没有工作簿
app=xw.App(visible=True, add_book=False)
#打开数据文件,可写
bk=app.books.open(fullname=root+\
r'\统一列数据的单位.xlsx',read_only=False)
sht=bk.sheets(1) #获取第1个工作表
#工作表中第2列数据最大行号
rows=sht.api.Range('B2').End(Direction.xlDown).Row
n=1 #记录当前行号
#遍历数据区域的单元格
for rng in sht.range('B2:B'+str(rows)):
n+=1 #行号加1
str0=rng.value #当前单元格中的字符串
strt=str0.replace('kg7;,'公斤') #将字符串中的kg替换为公斤
strt=strt.replace('千克7;,'公斤') #将字符串中的千克替换为公斤
sht.cells(n,2).value=strt #显示替换后的字符串
运行脚本,替换结果如图6-7中下表所示。