查看原文
其他

【基础篇】查找并输出子字符串的定位

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:喻淑敏,中南财经政法大学统计与数学学院

本文编辑:孙一博

技术总编:王子一

Stata&Python云端课程来啦!

       为了平衡团队运营成本,维系公众号的运营,也与国内动辄数千元的Stata课程缩短差距,我们的网课不得不上调价格,我们决定于2022年1月15日起调价,Python课程的价格调整为299.9元Stata进阶课程调为299.9元Stata基础课程调整到329.9元。大家可以告知一下身边想要购买的小伙伴,欲购从速哦,对报名有任何疑问欢迎在公众号后台和腾讯课堂留言~我们在这篇推文提供了每门课程的课程二维码,大家有需要的话可以直接扫描二维码查看课程详情并进行购买哦~此外,凭任意一篇推文集够50个赞,购买爬虫俱乐部的主要课程,即可获得50元的优惠,大家赶快行动起来吧~

导读

在使用Python进行编程的过程中,我们常常需要找到某个关键词在一个长字符串的位置。简单举例来说,比如,我们想要查找'love'在字符串'I love python.'中的位置,在Python中字符对应的位置如下表所示:

I
love
python.
012345678910111213
也就是说'I love python.'中,关键词'love'在字符串中的位置为2,那么我们要如何输出这个关键词位置的信息呢?如果想输出特定位置区间内关于这个关键词的信息该如何操作呢?那么,当一个长字符串中反复出现某子字符串,我们又该如何输出这个子字符串出现的所有位置呢?

一.输出子字符串首/末次出现位置


1.左边首次出现

在这里,我们介绍两个字符串方法:.index()和.find(),它们用来确定某关键词是否出现在我们所指定的字符串中,用法十分相似。
语法如下:
string.index(keyword, beg=0, end=len(string))string.find (keyword, beg=0, end=len(string))
其中,keyword是我们指定检索的关键词;beg是进行检索的开始,默认为0,也就是默认从字符串的第一个字符开始;end是进行检索的结束,默认为字符串的长度,也就是默认到字符串的最后一个字符结束。
代码如下:
#定义原字符串与子字符串str = 'I love python.'keyword = 'python'#用index查找并输出print(str.index(keyword))#用find查找并输出print(str.find (keyword))

二者不同点在于:index()查找失败时直接报错,会影响后续程序运行;而find()查找失败时则返回-1,且不会影响程序运行。
代码如下:
str = 'I love python.'keyword = 'stata'
#查看index()查找失败时的结果print(str.index(keyword))

str = 'I love python.'keyword = 'stata'
#查看find()查找失败时的结果print(str.find(keyword))

2.右边首次出现

不是所有的情况都是需要输出左边首次出现子字符的位置,有时我们需要知道右边首次出现子字符的位置,那么照搬index()与find()函数便不再生效,这个时候我们可以选用rindex()与rfind()来查询。区别仅在于后者查询的是右边首次出现的位置,而前者是左边首次出现位置;同时二者在语法使用、结果输出、结果解释上面基本无异。
语法如下:
string.rfind(str, beg=0,end=len(string)) #类似于 find(),不过是输出右边首次出现位置.
string.rindex(str, beg=0,end=len(string)) #类似于 index(),不过是输出右边首次出现位置.
代码如下:
str = 'I love python.'keyword = 'n'
print(str.rindex(keyword))print(str.rfind(keyword))


二.输出子字符串在指定区间内
出现位置

值得我们注意的是,无论是用.index()方法还是.find()方法,都只能返回关键词在字符串中出现的第一个位置(rfind和rindex同样如此),举一个简单例子就可以看出:比如,现在我们把关键词选为在字符串中出现了2次的'is':
str = 'This is my favorite course.'keyword = 'is'print(str.find(keyword))
此时,结果只输出了关键词’is’在字符串中出现的第一个位置2,而没有输出第二个位置5。如果我们想要输出第二个位置,就可以指定检索的开始和结束位置,比如我们分别输出将检索开始设置成0,结束设置成3和开始设置成4,结束设置成7:
str = 'This is my favorite course.'keyword = 'is'
#find从0位置开始寻找、4位置结束print(str.find(keyword,0,4))
#find从4位置开始寻找、7位置结束print(str.find(keyword,4,7))

根据上述例子,我们能够得到输出子字符串在指定区间内出现位置的代码了:
str='原字符串'keyword='子字符串’
#指定区间下界为开始查询位置,即begin 指定区间下界为结束查询位置,即end=‘’print(str.find(keyword,指定区间下界,指定区间上界))

三.输出子字符串出现的所有位置

如果想要输出某个关键词在一个长长的字符串中出现的所有位置,该怎么做呢?

1.re.finditer()方法
命令格式:
import re #调用python的re模块,以用于后面使用 re.finditer 函数
[substr.start() for substr in re.finditer(子字符串 , 原字符串)]
为了更好的理解上述命令,我们先做两个相关知识的引申:
其一,引申Python中常用的正则表达式处理函数
方法/属性作用
match()决定 RE 是否在字符串刚开始的位置匹配
search()扫描字符串,找到这个 RE 匹配的位置
findall()找到 RE 匹配的所有子串,并把它们作为一个列表返回
finditer()找到 RE 匹配的所有子串,并把它们作为一个迭代器返回

     针对 match()、seerch()、finditer()这三个正则表达式处理函数,如果匹配成功则返回一个Match Object对象,

     该对象有以下属性、方法:

方法/属性作用
group()返回被 RE 匹配的字符串
start()返回匹配开始的位置
end()返回匹配结束的位置
span()返回一个元组包含匹配 (开始,结束) 的位置
二,引申列表推导式
格式:[表达式 for 变量 in 列表]  或 [表达式 for 变量 in 列表 if 条件],举例如下:
list = [1,2,3,4,5,6,7,8,9]outcome=[x**2 for x in list]print(outcome)
输出如下:

在理解了“正则表达式处理函数”、“列表推导式”等概念后,我们终于可以来看一下 [substr.start() for substr in re.finditer(子字符串 , 原字符串)] 这条代码了,其中:
1.substr.start()表示输出的为变量substr的位置,并存放在一个列表中。
2.我们是用re.finditer函数在原字符串中查找所有子字符串,并把它们作为一个迭代器返回。
3.for则表明需要遍历re.finditer的所有返回值。
针对上述命令,举例可得代码如下: 
#为了说明begin是从0开始计数的str2 = '121315816'sub='1'
import re [substr.start() for substr in re.finditer(sub , str2)]

其实,还有一种简写方法。
但是,由下方实例可知,此方法和上面所述的方法基本原理相同,只是前者begin=0,而后者在以引入i进for循环时begin是从1开始计数
代码如下:
#为了说明begin是从1开始计数的
import re
all_position1 = [i.start() for i in re.finditer('1', ' 121315816')] print(all_position1)


2.利用循环语句搭配find()函数

#定义原字符串与子字符串str2 = '''The China Flower Association (CFA) said in a recent statement that the peony was recommended as China’s national flower, sparking heated debate online.'''keyword= 'on'
#将检索的开始设置成字符串中的第一个字符begin =0
#用循环来更新positionwhile True: position=str2.find(keyword,begin) #用if条件句控制循环终止与否 if position == -1 : break
#print所有position print("{} is found at position {}".format(keyword,position)) #控制循环条件来将检索的开始设置为此次输出位置的下一个字符处 begin= position + 1
让我们一步步来解释:
1.定义字符串及子字符串
2.用find()函数将检索的开始设置成字符串中的第一个字符,将关键词’on’在字符串中的第一个位置放在变量position中;
3.结合.format()方法输出该位置;
4.接着命令“begin= position + 1”将检索的开始设置为此次输出位置的下一个字符处;
5.结合while循环重复上述步骤更新position,并继续输出关键词所在位置,用if条件句设置当输出位置为-1,即字符串中不包含关键词时(find函数输出为-1时表示此时字符串不包含子字符串),终止循环。运行结果如下:


END

最后,我们为大家揭秘雪球网(https://xueqiu.com/)最新所展示的沪深证券和港股关注人数增长Top10。





腾讯课堂课程二维码








            


 对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!












往期推文推荐 

        Stata中的小清新命令——添加观测值

        PCA(主成分分析法)降维——Python实现

       超好用的事件研究法

        如何绘制任泽平《鼓励生育基金》的几幅图

        Python 第六天——字符串

        findname——想要什么找什么

        Python字符串之“分分合合”

        PDF转docx可批量操作?——wordconvert的小技巧

        考研之后,文科生需以“do”躬“do”!

       手绘五星兴家国——用Stata绘制五星红旗

        Seminar丨董事会的性别多样化和企业创新:来自国际的证据

       Python与数据库交互——窗口函数

        Stata之post命令——数据邮递 

        爬虫俱乐部成员的Stata学习经验分享来啦!

       Seminar丨2002年萨班斯·奥克斯利法案的经济后果

        我几乎画出了“隔壁三哥”家的国旗

        Python基础——三大数字类型,你都了解吗?
        如何用Stata绘制带指向性箭头标注的图像       
       Seminar丨荐仆贷款——19世纪中国的信任辅助贷款       【技能篇】多进程队列间通信

Seminar丨公司董事会的人才增长:来自中国的证据

正则表达式--懒惰模式

爬完独立董事的年薪,我的眼镜跌破了!识别旅游“照骗”——看风景名胜是否名副其实主成分分析的Python实现

正则表达式--贪婪模式

Seminar丨谁更重要:高管股权薪酬与财务报告欺诈DOS能量,超乎你想象!

爬虫实战丨走进哈利波特的魔法世界

数据集合并的新路子-frlink命令

Seminar丨附近的公司:利用卫星图像研究本地信息优势

线性同余法生成伪随机数 

[技能篇]多线程爬虫

“好哭”是衡量一部好电影的标准吗?

Stata&Python云端课程来啦!

关于我们 


   微信公众号“Stata and Python数据分析”分享实用的Stata、Python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。

   武汉字符串数据科技有限公司一直为广大用户提供数据采集和分析的服务工作,如果您有这方面的需求,请发邮件到statatraining@163.com,或者直接联系我们的数据中台总工程司海涛先生,电话:18203668525,wechat: super4ht。海涛先生曾长期在香港大学从事研究工作,现为知名985大学的博士生,爬虫俱乐部网络爬虫技术和正则表达式的课程负责人。



此外,欢迎大家踊跃投稿,介绍一些关于Stata和Python的数据处理和分析技巧。

投稿邮箱:statatraining@163.com投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里
为作者署名,并有赏金分成。

2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众
号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存