准备: —安装RegExpBuddy软件——专门测试正则表达式是否正确的软件 —或是找一个正则表达式在线测试网站 1.正则表达式——Regular Expression 什么是: 正则表达式,是专门描述字符串中字符出现规则的表达式。 为什么: 因为程序不认识人类语言中的词汇,所以才需要程序员用正则表达式教程序认识人类语言中的词汇。 可用于: 1.验证字符串格式 2.查找敏感词 定义正则表达式: (1).普通字符 所有的单个大小写字母、数字都是一个正则表达式,用以匹配单个字符,这个字符与它本身相同,简单来讲,就是一个关键词原文。 —例如:"我是" 关键词匹配的过程: 在RegExp Buddy中 —查找一句话中是否包含敏感词“我是” —如果将一句话中的“我是”,换成“我事”,还能查询出来吗? (2).字符集 问题: 第二个字符换成另一个同音字,就匹配不到了 解决: 字符集 什么是: —字符集是规定一位字符上多种备选字的列表 —只要规则中某一位字符上有多种备选字时,就用字符集 如何: [备选字列表] 例如: 匹配时,只要与[]中任意一个字符匹配,就算满足规则 字符集匹配过程: 如果再连上前边写死的“我”字规则,可匹配三种词: 在RegExp Buddy中 —定义一个规则同时匹配“我是” ,“我事” ,“我时” 三种敏感词 答案: 我[是时事] —扩展:修改规则,使其进一步匹配“卧是” 答案: [我卧][是时事] —[我卧][是事时]匹配过程: 再例如: 常用手机号规则: — 第一位:1 — 第二位:3、4、5、6、7、8、9中选其中一个 — 后 9位:每一位上都是在0~9数字之间任选其一 —结果: 问题: 如果每个数字都写很麻烦。 解决: 简写:如果[]中部分备选字符连续,可以使用-省略中间字符 例如: 手机号规则中: [3456789] 可简写为 [3-9] 读作 3到9 [0123456789] 可简写为 [0-9] 读作 0到9 所以,手机简写形式: 1[3-8][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] 其它简写: 要匹配 一位小写 字母 : [a-z] 共26个 要匹配 一位大写 字母 : [A-Z] 共26个 要 匹 配 一 位 字 母 : [A-Za-z] 共52个 要匹配一位字母或数字:[0-9A-Za-z] 共62个 要 匹 配 一 位 汉 字:[\u4e00-\u9fa5] 19968 ~ 40869 共20902个 使用字符集简写: 在RegExp Buddy中 —利用字符集简写定义车牌号规则: — 第一位:1位汉字 — 第二位:1位大写字母 — 第三位:· — 后五位:每一位都是一位大写字母或数字 —答案: [\u4e00-\u9fa5][A-Z]·[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z] (3).预定义字符集 正则表达式语法为四种最常用的字符集定义了最简化写法,称为预定义字符集。 包括: 要 匹 配 一 位 数 字 : \d 等效于 [0-9] 要匹配一位字母、数字或_: \w 等效于 [0-9A-Za-z_] 要 匹 配 一 位 空 字 符 :\s 可匹配 空格、制表符、Tab等空白 要匹配所有文字 (通配符) : . 所以,利用预定义字符集简写手机号规则为: 1[3-8]\d\d\d\d\d\d\d\d\d 问题: 手机号规则中\d写了9遍,车牌号规则中[0-9A-Z]也写了五遍,也很不方便。 原因: 一个字符集(\d或[0-9])只能匹配一位字符,要匹配9位字符,就必须重复写9遍。 程序用规则匹配字符串,就像彩票兑奖一样,是逐字逐个规则匹配。 不但内容要符合规则,位数首先要一致。 [\u4e00-\u9fa5][A-Z]·[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z] 解决: 使用数量词。 (4).数量词 什么是: 数量词,是专门规定一个字符集出现次数的规则 何时: 今后,只要一个字符集在规则中可能连续反复出现多次,就要用数量词以简写方式定义出现次数。 如何: 数量词紧跟在其修饰的字符集之后,默认修饰相邻的前一个字符集 例如: 利用数量词进一步简写手机号规则中,可进一步简写为: 1[3-8]\d{9} \d{9} 相当于 \d*9次 使用数量词: 利用数量词进一步简写车牌号规则,可进一步简写为: [\u4e00-\u9fa5][A-Z]·[0-9A-Z]{5} 问题: 接收短信验证码时,网站验证码有时4位,有时6位,并不确定,怎么办? 其实,数量词包括两大类: 1). 有明确数量边界的数量词 字符集{n} 表示字符集必须重复n次,不能多也不能少 例如: \d{4,6} 表示4位数字 字符集{n,m} 表示字符集至少重复n次,最多重复m次, 例如: \d{4,6} 表示4到6位数字 字符集{n,} 表示字符集匹配的内容至少重复n次,多了不限 例如: \d{6,} 表示6位以上数字 2). 没有明确数量边界的数量词 * 表示可有可无,多了不限 \s* + 表示至少一次,多了不限 \s+ ? 表示可有可无,最多一次 \s? 在RegExp Buddy中 —匹配手机短信中的验证码:连续的4位~6位数字 答案: \d{4,6} —匹配字符串中的一组连续空字符 答案: \s+ (5).选择和分组 问题: 屏蔽敏感词时,输入者把字换成拼音就查不出来了 错误的做法: 直接将拼音放入[]中作为字符集中的备选 比如: [草cao] 希望: 草 或 cao 原因: 字符集只认识单个字,不认识一组拼音 正确做法: 1).选择 什么是: 选择,是指在多个子规则中选其一匹配 何时: 今后,只要在多个子规则中选其一匹配时,就用选择 如何: 子规则1 | 子规则2 读作: 满足规则1 或 满足规则2 例如: 草 | cao 问题: 如果规则写成“我草|cao” 呢? 希望是: 我草 或 我cao 实际却是: 我草 | cao 原因: 因为“|”选择符只分左右,不考虑单个字符 解决: 使用分组。 2).分组 什么是: 分组,将多个子规则视为一组,再和分组外的规则匹配 何时: 只要希望将多个子规则视为一个整体,再和其它规则匹配时,就用分组 如何: 其它规则(多个子规则) 例如: —匹配一个“草” 字或“cao”这个拼音 答案: 草|cao —匹配“我草”或“我cao” 答案: 我(草|cao) 使用选择和分组: 问题1: 同时验证敏感字同音字或拼音,我草、我艹、我cao、我槽 答案:我 ([草艹槽]|cao) 问题2: “我” 字也可能是“卧”或“wo” 答案:([我卧]|wo)([草艹槽]|cao) 问题3: 可能在中间加不确定个数的空字符: 答案:([我卧]|wo)\s*([草艹槽]|cao) 在RegExp Buddy中定义规则 —匹配“我草” —匹配 “卧 槽” —匹配 “wocao”,“我 草”等敏感词 —定义完整手机号规则: 分析: +86或0086:(\+86|0086) 至少一个空字符 : \s+ 之前所有,整体可有可无,最多一次: ()? 1 3~9 任选其一 9位数字 答案: ((\+86|0086)\s+)?1[3-8]\d{9} —定义完整身份证号规则: 分析: 15位数字: \d{15} (一代身份证) 2位数字: \d\d 最后一位: 1位数字或Ⅹ: [0-9Ⅹ] 最后三位 可有可无,最多一次 (最后三位)? 答案:\d{15}(\d\d[0-9x])? (6).指定匹配位置 一个字符串中三个位置比较特殊: —1. 字符串开头 —2. 字符串结尾 —3. 英文句子中的每个单词中间的空白位置 如果只希望匹配特殊位置上的关键词时,就可用特殊符号表示特殊位置。 包括: —1. ^ 表示字符串开头 —2. $ 表示字符串结尾 —3. \b 表示单词边界,可匹配:空格,标点符号,字符串开头和结尾等可将一个单词与其它单词分割开的符号。 例如: 匹配一组连续的空字符 —1. 匹配任意一组连续的空字符 —2. 仅匹配开头的空字 —3. 仅匹配结尾的空字符 —4. 同时匹配开头和结尾的空字符: 错误的做法: ^\s+$,表示从开头到结尾之间只能是空字符! 正确做法: 用“|”选择符,将整个规则强行一分为2 再比如: 找到每个单词首字母 —前边紧挨着单词边界的字母 附图片(不与博客内容匹配,仅参考):
|
|