正则表达式游戏的答案
两天过去了,我们才送出了四个番茄钟(其中一个还是作为礼物送给了鲁鸿驹先生,感谢鲁鸿驹的现场莅临指导 ,鲁总是VIM的fans,多年不编程的他还记得是删除一行的指令是 dd )。
有一位F4的兄弟,我们忘记记录你的姓名了,请你接受我们的致敬!你回办公室Notepad++上验证好了正则表达式,然后来现场,因为VSCode的Regexp的语法同Notepad++存在的些许差异,差一点点就通过了,即便如此,我们仍然送出了一个番茄钟,希望你能进一步利用好番茄钟和番茄工作法,进一步提高办公效率。
题目没有要求来编程实现,而是要求在编辑器中完成,并且没有限制用什么编辑器。在这里,我们主要使用 Visual Studio Code。为什么主要是 VSCode,往下看就知道了。
游戏一(难度系数):
一个文本文件中有不少电话号码,它们的格式是用 1 开始的连续11位数字。比如:13923781654。现在为了规范,需要将他们转换为 139-2378-1654 这样3-4-4的分段格式,中间用短横线分隔。请你在一个编辑器中使用Replace功能,一步完成所有的转换。
解答:
在 VS Code 中用 Ctrl + H 调出 Replace ;
在 Search 框中输入 b(1d)(d)(d)b 。说明,这里前后加入的 b是限定符,匹配字的边界(开头或者结尾);如果不用 b,那么可能连续14或者15个不是有效的电话号码都会被匹配替换。
在 Replace With 框中输入 $1-$2-$3
注意打开“使用正则表达式”的选项开关(快捷键 Alt + R);
然后选择 Replace All,如图:
游戏二(难度系数):
我们写代码的时候,一不小心会在代码行后面留下一些多余的空格、Tab等。现在请你针对一个源文件,一次性的将所有代码行末尾多余的空格/Tab 字符全部删除掉;也就是说,每一行的回车换行符前面不能是空字符。
解答:
在 Search 框中输入 s+$ 。说明:s表示空字符(空格或者tab),s+表示一个或者多个连续的空格,$表示行尾;
Replace 框中保持为空
点击 Replace All
游戏三(难度系数):
我们写代码的时候,往往会不经意之间留下一些连续的空行。空行,就是只有回车换行、空格、Tab的行。我们把连续两个或两个以上的空行,叫做连续空行。连续空行不美观、占用屏幕空间,现在请你在编辑器中,一步将所有的连续空行换成单独一个空行。
解答:
Search 框中输入 ^(s*n)。说明:^表示行首,s*n表示0个或者多个连续空字符然后跟着一个换行符,表示至少两个的重复;
Replace 框中输入 n
点击 Replace All
游戏四(难度系数):
把代码中所有的十六进制数字(以 0x或者0X 开始的数字),转换成大写字母。例如把 0xab12ff00,转换成 0XAB12FF00。
解答:
编辑器 Visual Studio Code 对此无能为力了(一般的编辑器也都是奈何不了的),必须祭出大杀器VIM,步骤如下:
用Vim 打开这个文件
按几下 ESC ,进入命令模式
输入如下命令 :%s//U&/gi
回车,所有的十六进制就变成大写了
稍微解释一下:VIM 的 regex 语法和VSCode的不太一样,功能也强大很多,%s 表示对所有的行进行查找替换,%s/xxx/yyy/g ,意思就是把所有行中的 xxx 都替换成 yyy,这里是替换成 U& ,意思就是把匹配到的所有目标串变成大写。如果 L& ,那就是换成小写。命令最后的 g 表示全部替换, i 表示查找的时候不区分大小写,这样 0x 和 0X 开始、或者原来就存在大写字母的的十六进制数字都会被找出来并且替换掉。
这里替换模式用 < 和 > 包围起来了,这和 VSCode 里面的 b 是类似效果,避免错误的匹配和替换;
如果需要每次替换前都确认下,那么在最后加上c,写成 gic,这样VIM每次替换前都会要求你确认是否替换;
如下图,看起来是不是很炫酷?
游戏五(难度系数)
测试脚本用 Ruby 写成,里面定义了一系列的函数,ruby 的函数定义格式如下
def foo()
# ...
end
这个文件的 ruby函数定义都在单独一行,def 左边只能有空格或者顶头开始,def和函数名之间有一个或者多个空格。现在要求给本文件的所有函数改名,在原名字的前面加上模块名 AAA,例如将 foo 修改成 AAA_foo。
解答:
还是回到 Visual Studio Code,打开 Replace 对话框,操作步骤如下:
Search 中输入 ^(s*defs+)([_a-z0-9]+)
Replace With 中输入 $1AAA_$2
选择 Replace All;
使用正则表达式进行编辑(查找、替换)一个常用技巧,就是通过特定的子串来缩小替换范围,比如上面的例子中,^(s*defs+) 这个子串,它表示顶行开始 def 关键字,其实并不是我们想要进行替换操作的对象,但是我们仍然要把它放在这里,目的就是通过它筛选出所有的函数名,只有跟在这个特定的def之后的名字,才是我们要替换的函数名。
正则表达式是非常强大的、有趣的东西。套用一句广告语:谁用谁知道啊!从上面的几个例子也可以看到,不同的编辑器,其所采用的正则表达式的语法也是存在差异的,比如VSCode里面表示1个或者多个重复,用 +,但是在vim里面,必须用 +,为了高效使用正则表达式,选定一个固定的好编辑器并且用熟练,是很有必要的。否则我们的时间就会浪费在查找 regexp 的语法细节上。
- mysql 性能优化方案 (转)
- 《Redis设计与实现》读书笔记(一)——简单动态字符串(SDS)
- Comet:基于 HTTP 长连接的“服务器推”技术
- 编码修炼 | 快速了解Scala技术栈
- VFS四大对象之三 struct dentry
- PHP 排序算法实现讲解
- PHP7新特性介绍
- VFS四大对象之四-struct file
- 《Redis设计与实现》读书笔记(二) ——Redis中的字典(Hash)
- 《Redis设计与实现》读书笔记(三) ——Redis中的链表
- 《Redis设计与实现》读书笔记(四) ——Redis中的跳跃表
- 解析Linux中的VFS文件系统之文件系统的注册(二)
- vivi虚拟摄像头驱动程序
- 系统架构 | 基于微服务架构,改造企业核心系统之实践
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- SAP Spartacus OccEndpointsService单元测试的依赖注入
- Python利用PyPDF2库获取PDF文件总页码实例
- TypeScript里get属性的实现
- SAP Spartacus OccEndpointsService单元测试之getBaseEndpoint
- html+css入门基础案例之圣诞那些事
- 建议收藏备查!MySQL 常见错误代码说明
- html+css入门基础案例之页面设计
- Github 星标 8K+ 这款国人开源的 Redis 可视化管理工具,真香...
- CSS3 2D转换
- CSS3 3D转换
- python传到前端的数据,双引号被转义的问题
- H5C3综合案例
- 移动web开发之rem适配布局
- Android面试题问答整理
- 移动开发之响应布局