文盲的Python入门日记:第四天,用一个小练习来熟悉一下python的列表和其他语言数组的不同,以及Python的正则

编程入门 行业动态 更新时间:2024-10-10 12:22:55

文盲的Python入门日记:第四天,用一个小练习来熟悉一下python的列表和其他语言数组的不同,以及Python的<a href=https://www.elefans.com/category/jswz/34/1767706.html style=正则"/>

文盲的Python入门日记:第四天,用一个小练习来熟悉一下python的列表和其他语言数组的不同,以及Python的正则

文盲的Python入门日记:第一天,Python环境搭建

文盲的Python入门日记:第二天,连接到mssql和python代码书写初体验

文盲的Python入门日记:第三天,用一些小练习感受一下python的不同

文盲的Python入门日记:第四天,用一个小练习来熟悉一下python的列表和其他语言数组的不同,以及Python的正则

文盲的Python入门日记:第五天,搭建一个python调试环境,以及初步探索pymssql的使用

文盲的Python入门日记:第六天,继续完善我们的MsSql类,支持查询结果的筛选和排序,以及日期类型

-----------------------------------------------------------------------------

今天在csdn问答看到一个比较有意思的题目,拿过来练练手,题目地址,题目描述如下:

对一个字符串进行关键字屏蔽,但无论多少关键字被屏蔽,只要是连续的屏蔽,只返回一个屏蔽结果

对于这个题目,文盲的第一反应是用正则来完成,Hmmmm。。。

先用常规的编程方式试试看,继续以前的套路,上几个不同环境的代码

// js 继续做先锋
var source = [3,'ot','out','lotof','alotofsmallottoyoutmyhouse,anotoutatotroom'];
var mask = function(a){var l=a[0],c=[];for(var i=0;i<l;i++){c.push(a[i+1])}var s = a[a.length-1];var m = []; var result = '';for(var i=0;i<s.length;i++){for(var j=0;j<c.length;j++){if (s.substr(i,c[j].length)==c[j]){for(var x=0;x<c[j].length;x++){if (m.indexOf(i+x)<0){m.push(i+x)}}}}}for(var i=0;i<s.length;i++){if (m.indexOf(i)<0){result+=s.substr(i,1)}else{while(m.indexOf(i+1)>=0){i++}result +='**'}}return result
}
document.write(mask(source))
// a**small**toy**myhouse,an**at**room

这个代码的思路已经在问答的回复里讲过了,这里就不水字数了

// C# 再次登场private string mask(object[] a){string result = string.Empty;int l = (int)a[0];List<string> c = new List<string>();for (int i = 0; i < l; i++){c.Add((string)a[i + 1]);}string s = (string)a[a.Length - 1];List<int> m = new List<int>();for (int i = 0; i < s.Length; i++){for (int j = 0; j < c.Count; j++){if (s.Length - i >= c[j].Length && s.Substring(i, c[j].Length) == c[j]){for (int x = 0; x < c[j].Length; x++){if (!m.Contains(i + x)){m.Add(i + x);}}}}}for (int i = 0; i < s.Length; i++){if (!m.Contains(i)){result += s.Substring(i, 1);}else{while (m.Contains(i + 1)){i++;}result += "**";}}return result;}object[] source = new object[] { 3, "ot", "out", "lotof", "alotofsmallottoyoutmyhouse,anotoutatotroom" };
string result = mask(source);

在C#的代码中,明显可以看出和js的不同了,为了支持不同类型的数据在一个数组中,我们只能用object[]来代替,然后在使用的时候还要转换类型,再一个就是substring的问题,js里有两个类似的方法,一个substr(pos,len),另一个是substring(start,end),可千万不要弄混了,c#里则只提供了一个substring(pos,len),然后就是数组索引的问题,在js里,substr超出索引不会报错,在c#里,则不可以,所以还要追加一个判断,避免超出字符串长度

source = [3,'ot','out','lotof','alotofsmallottoyoutmyhouse,anotoutatotroom']
def mask(a):l=a[0]c=a[1:-1]s=a[-1]m=[]result=''for i in range(len(s)):for j in range(len(c)):if s[i:i+len(c[j])]==c[j]:m = list(set(m).union(set(range(i,i+len(c[j])))))for i in range(len(s)):if i in m:if i+1 in m:continueresult += '**'else:result += s[i:i+1]return result
print(mask(source))

啊咧。。。。python的代码写完测试通过后,怎么觉得以前编程弄的都很累赘呢?python这才几行就完成了?嗯。。。嗯。。。。。Hmmmmmmmmm。。。。。。很好,很强大,开始总结一下文盲的感受吧。

1、循环变简单了,缩进结构代替了{}结构,除了缩进要求,行数确实变少了,循环问题第三天的时候也说过了,这里不再多说

2、python的列表和集合的结合使用,使得列表(其他语言的数组)交集、并集、差集、补集变得简单而优雅,同样在变量m中追加新的元素且不得重复,在js和c#中,都需要循环并挨个判断,到了python这里,直接用集合并集返回列表。。。

3、关于循环控制,在python中,由于for是遍历循环,所以不再可以使用循环体内,用循环变量自增的方式了,必须用continue来完成

4、字符串截取。。。。这个还真是一言难尽,c=a[1:-1]这种用法实在是。。。。真香

本来打算用正则完成这个题目的,但是在实际操作后发现,正则方法真要实现这个题目,会复杂务必,而且不是一次正则可以完成的,可能会出现正则叠加,正则嵌套等乱七八糟的玩意,就不再用正则实现上边的题目了,直接用正则完成一些常见的操作,来比较一下有没有什么特别的不同

如果不懂正则,或者正则基础不太好的,还没把正则吸纳成为自己的东西的同学,可以先看看文盲的正则入门,传送门

先列举一下正则使用方式

// js 的正则// 创建正则,使用 RegExp(正则表达式,正则修饰),适合拼接出来的正则表达式
// 创建正则,使用 /正则表达式/正则修饰,该方法不支持拼接正则表达式// js 的字符串中支持正则方法有match和replace'abc'.match(/(.)(?!$)/gi) // ['a','b']
'abc'.match(/(.)(?!$)/i)  // ["a", "a", index: 0, input: "abc", groups: undefined]// js match 加 g 修饰与不加 g 修饰区别很大,自己注意哦
// 加 g 修饰,匹配全部内容,只返回匹配项到数组
// 不加 g 修饰,匹配第一项,并返回该匹配的位置及分组匹配的内容'abc'.replace(/.(?!$)/gi,'*') // **c
'abcdefg'.replace(/./gi,function(){return arguments[1]%2==0?'*':arguments[0]}) // *b*d*f*// js 正则支持右断言,前边正则都看出来了
// js 正则支持分组引用,这里就不写了
// js 正则支持委托,可以用方法,也可以用闭包,上例就是将所有偶数位的字符替换成*// 对了,js字符串的 split 方法也可以使用正则// js 正则除了字符串支持的方法外,自身还带有部分方法// .test 测试是否匹配,这个不说了/(.{2})(?=$)/gi.exec('abcdef')  // 用法与字符串 match 不加g修饰一样// pile 重新编译正则,这个不好解释,通过例子来看看
var re = /(abc)$/gi;
re.test('123abc');  // true
re.test('123abc');  // false
re.test('123abc');  // true
re.test('123abc');  // falsevar re = /(abc)$/gi;
re.test('123abc');  // true
repile();
re.test('123abc');  // true
re.test('123abc');  // false
re.test('123abc');  // true// 简单来说,就是在js正则匹配时,正则变量本身记录了一些位置信息,这些信息会干扰下次使用
// 如果使用了 compile ,那么这些信息就重置了// 嗯,js 的正则基本上就这些用法
// 在 js 中,他不支持正则的左断言,不支持正则本身递归,不支持层深计算,嗯毕竟js也不是干这个用的,支持一些简单应用就很好了
// c# 中的正则// c# 中存在两种使用正则的方式 
// 一种是直接使用 Regex 静态类
// 另一种是自行实例化一个 Regex 对象
// 通常来讲,这个是没有什么区别的,但如果在大并发项目中,推荐使用实例化这个方式,或者自己封装一个静态类,每次使用时,在方法中自己重新实例化// c#正则支持的方法,有IsMatch,Match,Matches,Replace,Split// IsMatch 不说了,和 js 的 test 一样,检查是否匹配
// Match 则和不加 g 修饰的字符串match,或正则exec方法一样,不过这个返回的是一个Match,里面信息就完整很多了,分组,位置,匹配成功与否等等乱七八糟的信息都在了
// Matches,Match的升级版,返回一个MatchCollection,就是Match的数组
// Replace,正则替换,同样支持委托方法和闭包委托
// Split,用正则切割字符串// 简单来讲,c#中的正则使用方式,没啥区别,除了比js返回的数据完整些,好像没什么有点?// No no no,c#中,正则是支持左断言的,除了右断言,我们还可以回溯要匹配的内容,增加更多修饰// 一个左断言的例子Regex.Match("abcd12345cdef","(?<=\d)[a-z]+");  // 判断字符串中,是否存在数字之后的字母,并将数字之后的字母作为结果匹配出来// 除了左断言外,c#还支持层深的计算,在文盲的正则入门里,已经有详细讲解了,不再举例了
// 层深计算,方便我们完成部分内容完整性的验证,比如字符串内用<,则必须有对应的>才可以,我们就可以通过层深来验证了// 可惜的是,c#正则不支持递归,听说java是支持的,不过文盲没有亲自验证过// 嗯,c#中的正则不需要向 js 一样,每次都重新编译,正则就是正则,他不会记录无关信息,所有的信息都在返回结果里了

回顾完了 js 和 c#,然后看看 python的 

Python 正则表达式 | 菜鸟教程

看着教程来学习

先是 match 方法。。。。嗯,怎么说呢,很别扭的用法

这等于是说,不管我的正则表达式怎么写都是默认加了^字符串起始定义的?

实测一下吧

好吧,看起来match是只能匹配开始就匹配成功的内容,这个方法不太好用,继续学习

哦哦,有个search方法,看描述,这个才是我熟悉的 c# Match 用法,实测一下

Hmmmm.....还是不太一样,这个没有返回分组信息,返回结果也只有两个内容,索引信息和最终匹配结果

然后是 sub 方法,替换?难道是replace?sub是哪个单词的简写吗?搞不懂

re.sub(pattern, repl, string, count=0, flags=0)

不行了。。。。js 都是字符串写前边,正则表达式写后边,python这个是反着来的,所有的都反着来的!

js: 'abcdef'.replace(/./gi,'*')

c#:Regex.Replace("abcdef",".","*"),或者 new Regex(".").Replace("abcdef","*")

py:re.sub('.','*','abcdef')

位置完全不适应啊~~~~~

哦哦,在教程里没看到左断言的说明,还以为没有,结果这不是有左断言吗,吓我一跳

嗯嗯,继续sub方法的研究,支持委托方法,那么支持闭包吗?话说,python里有闭包吗?

.html

嗯嗯,看了这个文章,确定python里是有闭包的了,那么正则可以使用闭包吗?

尝试看看!

啊哦。。。至少命令行不支持,也许是我的写法有问题??感觉不太行的样子,毕竟要靠缩进来定义方法的话,我后边传入的字符串应该怎么写?以后再研究正则闭包委托的事,继续看,re 支持函数,那么,这个函数到底有几个参数?结果长时候只有一个参数,嗯就是匹配本身

结果在老顾看的这个python教程里Python 正则表达式 | 菜鸟教程,根本没有match匹配的完整说明,里面有什么属性,什么方法都不知道,这怎么继续?

好在度娘很强大,换个文章看看Python正则表达式及match函数的用法_python match函数用法_青苔凉透了我的心坎的博客-CSDN博客

import rea = '123456'def match(m):r = int(m.string[m.span()[0]:m.span()[1]])r += 1return str(r)b = re.sub('\d',match,a)print(b)// 234567

这。。。真的全是坑啊,一怒之下,干脆看 lib\re.py 里的内容吧!

哦哦,还有这么多道道呢啊

findall方法,返回一个列表,和js的match带g修饰类似啊

fullmatch方法,哦哦,比match更严格了,还默认加了字符串结尾$验证

subn方法,嗯嗯,返回值有变化,返回一个tuple了?原来是加了个替换的次数啊

最后,才是finditer方法

哦哦哦!!这个才是我心心念念的c#中的Matches方法啊,不过遍历这个迭代,只能遍历一次,嗯,需要自己把他拿出来用,可以自己定义个Matches方法用用了

so,关于正则的部分总结一下

1、py中没有ismatch、test之类的方法,只有match,fullmatch,search,没有结果的就是匹配不成功,否则就是匹配成功

2、py中,正则替换的关键字编程sub、subn了,暂时不知道能不能写闭包,但是支持委托函数

3、匹配时match类型有不少属性,可以类比c#中的Match对象了,虽然不完全一样

4、findall在普通场景下,比finditer方便,虽然少了很多信息,finditer在做复杂需求时,具有信息更完整的优势,对标c#中的Matches

5、split方法没看,看re.py里,没什么新意

6、py的正则说明里,在正则表达式中多了几个用法?

以后有机会再研究吧,今天先这样了。正在学python的同学可以和老顾一起学习哦。期待你们的留言。

更多推荐

文盲的Python入门日记:第四天,用一个小练习来熟悉一下python的列表和其他语言数组的不同,以及Python的正则

本文发布于:2024-03-04 13:17:50,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1709364.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:正则   数组   文盲   第四天   入门

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!