Python正则表达式解惑

其实我已经使用Python的正则表达式很久了,今天看了Pycon2017的一个speech[2],又加深了理解。这是一个很简单的Speech,概括了Python正则表达式的用法以及一些Best Practice。

其实正则表达式常用的就那几种,熟悉了就很强大了:

  1. [ ] 表示都可以匹配,比如[abc]匹配a或b或c
  2. {1,3}表示重复1-3次
  3. [^abc]表示非abc
  4. 一些常用的匹配比如.*?表示非贪婪地匹配任何东西

现在已经有很多正则表达式教程了(包括基本上任何Python入门教程都会涉及正则表达式),这里就不多说。我对Python的正则有几个疑惑,在这个视频里面找到了答案。

一、永远使用r前缀。

python的r前缀表示原字符串(raw_string),就是字面意思的字符串,\并不表示转移。比如说r’\n’表示的是一个反斜杠,一个字母n。如果不加r即’\n’,那么\就表示转移,\和n一起表示一个换行符。可以理解为r'\n' == '\\n'

二、正则表达式中需要转义的字符。

三、Python正则表达式groups和group的区别。

详细解释在我的这个gist:https://gist.github.com/laixintao/1a550e98726ddbada0268f6b6a6490cf

group – 是获得所有的匹配,第0个是整个匹配的字符串,后面的是子匹配

groups – 是获得所有的子匹配,接受一个参数作为default。类似dict的get用法。

参考资料:

  1. PyCon Slides: https://drive.google.com/file/d/0BxJ4y96AC8m3NEpreVZLcDl0Nlk/view
  2. PyCon youtube: https://www.youtube.com/watch?v=abrcJ9MpF60&t=205s
 

git-ext:在命令行提交PullRequests的小工具

我们主要用的仓库托管是 bitbucket,感觉不是很好用。每次推分支之后要打浏览器开 pr 很烦,而且要一个一个一个点 reviewers。就写了一个命令行工具,可以不用开浏览器搞这些东西了。其实主要是用的 REST 的 api 做了个客户端,授权是 HTTPBASIC,所以要将密码写到~/.git_ext.yml 。

安装:

主要特性:

  • 在命令行提交 pr,使用 git config 的 core.editor 来编辑 pr 信息,第一行是 title,其余是 description
  • pr 的模板会显示 source 分支和目标分支的 diff 和 stat
  • 如果 pr 提交失败(比如服务器并没有 source branch )会备份本次写的 pr 信息,下次 create 的时候,如果有存在上次失败的 commit message,会自动使用上次写的(不用重写一遍啦)
  • 支持 reviewers group,比如你设定了一个组 dev,里面有 10 个人,那么在命令行填写 reviewers 的时候只要写 @dev,reviewers 就会变成这 10 个人。
  • 支持查看服务器的 pr 列表
  • 支持查看 pr 的动态

放两张预览图:

TODO

  • 由于我提 pr 基本都是在 bitbucket,所以现在只写了 bitbucket,下面做 github 的吧(再下来是 gitlab,如果这东西有人用的话)。
  • snippets 和 gist 支持

源代码

https://github.com/laixintao/git-ext

话说,能工作和作为开源工具发布真是不一样啊,刚开始写的时候,基本上一个晚上就写好了,但是后来想加一下travis和codecov,折腾了好久。然后总觉得设计不好,想用面向对象,github bitbucket gitlab都从base的PullRequest继承,又重构了下,等于重写了一次,竟然有一百多次commits了。不过不写不知道,打包发布,ci,也有不少坑呢。

 

Vim:移动窗口和tab

Vim相比于IDE一个高效的地方就是可以快速移动和切换窗口,完全不必借助于鼠标。

开启多窗口非常简单:

  • 在NerdTree中使用s键或i键在当前的窗口中以横/竖分屏的方式打开目标文件
  • 在NerdTree中使用t/T在新的tab打开目标文件(区别在于是否focus到新的tab)
  • 在buffer中使用:split命令对当前buffer分屏
  • 使用:tabnew打开一个新的tab

在多个分屏中移动也很简单:

  • <CTRL+W>hjkl,光标在不同的分屏中移动
  • <CTRL+W>HJKL,将光标所在的分屏移动到最左/下/上/右
  • gt到下一个tab
  • gT到上一个tab

但是有时候有这样的需求:我在一个分屏的窗口编辑文件,想要将当前的这个分屏全屏化,也就是说,将目前的一个分屏作为一个新的tab。也很简单:<CTRL+W>T 将当前buffer作为一个新的tab打开。

又有时候有这样的需求:在一个tab中编辑文件,但是想要参考上一个tab中已经打开的一个窗口的内容,这时候想要将当前的tab变成上一个tab的一个分屏。其实这是很常用的需求,但是这比较难办了,搜了一圈没有发现这样的Vim内置功能。但是找到了一个同样作用的VimScript。

于是可以在.vimrc中加入这些代码,其实就是两个函数:

这两个函数可以做到,将tab变成上一个tab的一个分屏,或者将tab变成下一个tab的一个分屏。模仿之前有关tab的快捷键,我加了下面这两个映射:

这样使用mt可以快速移动tab了,亲测有效。至此好像在vim中没有什么移动是做不到了,可以穿梭自如了。

参考资料:

  1. Move current window between tabs
 

tmux、vim和系统剪切板公用问题

vim的剪切板和系统公用问题一直是一大痛点,粘贴少数文本的时候尚可,但是剪切带有换行的时候就完全乱了,下一行总是比上一行多缩进一次。对于我这种主要用python的人来说,这简直太难受了。之前我一直忍着,今天实在忍不了了,想找个方案解决这个问题,单最终还是没解决。

其实vim可以将文本剪切/粘贴自寄存器的,有一个"寄存器就和系统是公用的。在系统看vim --version是不是支持clipboard,如果没有的话,可以按照这里加上--with-clipboadrd重新编译一下vim。

我重新编译之后,发现clipboard那里已经是+了,但是发现还是不能粘贴到系统剪切板。才发现vim直接在终端模拟器下(比如我用的ITerm2)是支持的,但是在tmux下是不支持和系统剪切板公用的(发现tmux有很多不支持的地方,比如brew service)。查了一下,tmux也维护着一个剪切板(卧槽,幸亏iTerm2没有自己的剪切板),那么如果要实现vim到系统剪切板复制粘贴,要将vim和系统的剪切板通过tmux共享……

查了一下,发现这个插件:https://github.com/roxma/vim-tmux-clipboard但是尝试安装了,发现没啥用。


解决方案:

从终端向系统粘贴:在vim中是可以使用tmux进行剪切的(但可能会连行号一起剪切了,可以使用块剪切解决,不是大问题)。所以只要解决从终端向外剪切这个问题就好了。解决方案是写一个tmux脚本将tmux的buffer同步到系统的剪切buffer中,具体可以看这个commit。这个脚本用到了一个同步tmux和系统buffer的软件,安装方法:brew install reattach-to-user-namespace.

从系统向终端粘贴:粘贴到tmux没问题,但是粘贴到vim就可能出现下一行比上一行多缩进的情况。这是因为vim在下一行自动给你按照上一行缩进了。解决方法是粘贴的时候临时关闭这种缩进,使用vim命令: set paste


关于未解决的问题:


博客有一个分类是记录未解决的问题的,比如此文。但是发现这样管理不太好。所以打算换一个方案,在github上开了一个项目,只使用issue记录目前生活、编程等各方面未找到合适的解决方法的问题,等issue解决的话就关闭。如果值得分享的话再写一篇博文。

参考资料:

  1. http://harttle.com/2017/06/23/vim-tmux-clipboard.html
  2. http://foocoder.com/2013/07/28/zhong-duan-huan-jing-zhi-tmux/
  3. 终端环境之tmux
 

最近写程序的心得

最近更博客不频繁了,因为拿到毕业证之后可以安心写程序,不用操心别的事情了,所以感觉也懒惰了许多。书也没咋看,电影也没咋看,甚至游戏都不怎么玩了,今天才更新了守望先锋。

拿到毕业证之后入职,公司配了2015early版本macbook pro,8G/128G。感觉这电脑好漂亮啊,虽然比我的2013air是重了很多,但是屏幕的黑色边框,侧边的散热口,好像一体都是浑然天成的,也没有过时的感觉(当然我肯定也更喜欢最新款的mac啦)。缺点就是耗电太快了,和我的macbook air同样的使用,续航却比不过用了四年的老air,不过对我来说不是什么大问题,随处可以充电。另外值得一说的就是Retina显示屏,感觉打开了新世界的大门,网页上的任何东西都变漂亮了。不过终端上字体太锐利反而不怎么适用了。编程的显示还是不用太高的分辨率,因为来来回回也就是26个字母的显示。

最近在工作中有很多心得,第一个就是,实践才是检验真理的唯一标准。很多东西不太容易记,比如说python re的group,groups,每次用到都去查。有一次我有个东西也是不太确定,就问同事,同事说,你自己试试不就知道了。我一想也是。其实自己打开交互式终端测试一下也花不了太长时间,从网页上看到的知识,都是自己没检验过的,印象也不深刻,要说自己不尝试就完全理解,其实很难。当然,不看书和网页也不合适,书是一个总结、系统的过程,比如说你去看一个新的框架或者工具,一开始就自己尝试肯定不行,就像掉进大海一样,这时候如果稍微看看书肯定有“哦原来这个功能已经有一个专门的接口来实现了”的感觉。哎,说了这么多感觉和没说一样,就是“学而不思则罔、思而不学则怠”这个道理吧。

然后是,不要重复做事情。勤快的程序员不是好程序员。比如说吧,之前经常要做这样的事情,提交PR,然后别人提了意见,一般是通过amend再次commit的:

所以就把上面写成一个git命令,然后以后都用一条命令提交就行了。但是这个-A太危险了,又一次我把..DS_Store提交上去了,太丢人了呵呵。最近经常做的一件事就是对自己的pypi打包新版本,这就更复杂了,编辑版本号,打tag,push,upload,写了这个脚本来自动化。不过后来赵老师推荐了这个工具,也蛮好的。

说道赵老师,这是一个疯狂收藏东西的人。自动关注他之后,每天github都被刷屏。赵老师吐槽,自己的chrome如果不小心把鼠标移动到书签上,电脑就死机了,因为自己的书签太多了,内存爆炸,都显示不过来,不过后来赵老师申请了另一个google账户,重新开始chrome。

跑题了,回头说第三个心得。我发现大的项目测试有点麻烦,依赖太多了,任务队列、缓存、数据库等,所以尽量少测试几次效率就变高了。之前我写代码都很鲁莽,抱着一种“试一试吧,不行再改”的态度。估计得改改,尽量一次就写对,减少测试的次数,而且吧,这测试的一多了,人就变得不快乐了,不耐烦了。

就先写这么多吧,周末了,最近上海太热了,快四十度了,在家里打打游戏,看看书。