《JavaScript 闯关记》之正则表达式
正则表达式(regular expression)是一个描述字符模式的对象,使用正则表达式可以进行强大的模式匹配和文本检索与替换功能。JavaScript 的正则表达式语法是 Perl5 的正则表达式语法的大型子集,所以对于有 Perl 编程经验的程序员来说,学习 JavaScript 中的正则表达式是小菜一碟。 正则表达式的定义JavaScript 中的正则表达式用 // 推荐写法 var expression = / pattern / flags ; // 不推荐写法 var expression = new RegExp(pattern,flags); 其中的模式(pattern)部分,是包含在一对斜杠
因此,一个正则表达式就是一个模式与上述3个标志的组合体。不同组合产生不同结果,如下面的例子所示。 // 匹配字符串中所有"at"的实例 var pattern1 = /at/g; // 匹配第一个"bat"或"cat",不区分大小写 var pattern2 = /[bc]at/i; // 匹配所有以"at"结尾的3个字符的组合,不区分大小写 var pattern3 = /.at/gi; 与其他语言中的正则表达式类似,模式中使用的所有元字符都必须转义。正则表达式中的元字符包括: ( [ { ^ $ | ) ? * + . ] } 这些元字符在正则表达式中都有一或多种特殊用途,因此如果想要匹配字符串中包含的这些字符,就必须对它们进行转义。下面给出几个例子。 // 匹配第一个"bat"或"cat",不区分大小写 var pattern1 = /[bc]at/i; // 匹配第一个" [bc]at",不区分大小写 var pattern2 = /[bc]at/i; // 匹配所有以"at"结尾的3个字符的组合,不区分大小写 var pattern3 = /.at/gi; // 匹配所有".at",不区分大小写 var pattern4 = /.at/gi;
|
长属性名 | 短属性名 | 说明 |
---|---|---|
input | $_ | 最近一次要匹配的字符串。Opera未实现此属性。 |
lastMatch | $& | 最近一次的匹配项。Opera未实现此属性。 |
lastParen | $+ | 最近一次匹配的捕获组。Opera未实现此属性。 |
leftContext | $` | input字符串中lastMatch之前的文本。 |
multiline | $* | 布尔值,表示是否所有表达式都使用多行模式。IE和Opera未实现此属性。 |
rightContext | $' | Input字符串中lastMatch之后的文本。 |
使用这些属性可以从 exec()
或 test()
执行的操作中提取出更具体的信息。请看下面的例子。
var text = "this has been a short summer"; var pattern = /(.)hort/g; /* * 注意:Internet Explorer 不支持 multiline 属性 * Opera 不支持 input、lastMatch、lastParen 和 multiline 属性 */ if (pattern.test(text)){ console.log(RegExp.input); // this has been a short summer console.log(RegExp.leftContext); // this has been a console.log(RegExp.rightContext); // summer console.log(RegExp.lastMatch); // short console.log(RegExp.lastParen); // s console.log(RegExp.multiline); // false }
如前所述,例子使用的长属性名都可以用相应的短属性名来代替。只不过,由于这些短属性名大都不是有效的 JavaScript 标识符,因此必须通过方括号语法来访问它们,如下所示。
var text = "this has been a short summer"; var pattern = /(.)hort/g; /* * 注意:Internet Explorer 不支持 multiline 属性 * Opera 不支持 input、lastMatch、lastParen 和 multiline 属性 */ if (pattern.test(text)){ console.log(RegExp.$_); // this has been a short summer console.log(RegExp["$`"]); // this has been a console.log(RegExp["$'"]); // summer console.log(RegExp["$&"]); // short console.log(RegExp["$+"]); // s console.log(RegExp["$*"]); // false }
除了上面介绍的几个属性之外,还有多达9个用于存储捕获组的构造函数属性。访问这些属性的语法是 RegExp.$1
、RegExp.$2
...RegExp.$9
,分别用于存储第一、第二...第九个匹配的捕获组。在调用 exec()
或 test()
方法时,这些属性会被自动填充。然后,我们就可以像下面这样来使用它们。
var text = "this has been a short summer"; var pattern = /(..)or(.)/g; if (pattern.test(text)){ console.log(RegExp.$1); // sh console.log(RegExp.$2); // t }
这里创建了一个包含两个捕获组的模式,并用该模式测试了一个字符串。即使 test()
方法只返回一个布尔值,但 RegExp
构造函数的属性 $1
和 $2
也会被匹配相应捕获组的字符串自动填充。
模式的局限性
尽管 JavaScript 中的正则表达式功能还是比较完备的,但仍然缺少某些语言(特别是 Perl)所支持的高级正则表达式特性。下面列出了 JavaScript 正则表达式所不支持的特性。
匹配字符串开始和结尾的A和Z锚
向后查找(lookbehind)
并集和交集类
原子组(atomic grouping)
Unicode支持(单个字符除外,如uFFFF)
命名的捕获组
s(single,单行)和x(free-spacing,无间隔)匹配模式
条件匹配
正则表达式注释
即使存在这些限制,JavaScript 正则表达式仍然是非常强大的,能够帮我们完成绝大多数模式匹配任务。
关卡
按要求完成下列常用的正则表达式。
// 挑战一:数字 var pattern1 = null; // 补全该正则表达式 console.log(pattern1.test('123')); // true console.log(pattern1.test('abc')); // false
// 挑战二:3位的数字 var pattern2 = null; // 补全该正则表达式 console.log(pattern2.test('123')); // true console.log(pattern2.test('1234')); // false
// 挑战三:至少3位的数字 var pattern3 = null; // 补全该正则表达式 console.log(pattern3.test('1234')); // true console.log(pattern3.test('12')); // false
// 挑战四:3-5位的数字 var pattern4 = null; // 补全该正则表达式 console.log(pattern4.test('1234')); // true console.log(pattern4.test('1')); // false
// 挑战五:由26个英文字母组成的字符串 var pattern5 = null; // 补全该正则表达式 console.log(pattern5.test('abc')); // true console.log(pattern5.test('1abc')); // false
// 挑战六:由数字和26个英文字母组成的字符串 var pattern6 = null; // 补全该正则表达式 console.log(pattern6.test('1abc')); // true console.log(pattern6.test('_abc')); // false
// 挑战七:日期格式:年-月-日 var pattern7 = null; // 补全该正则表达式 console.log(pattern7.test('2016-08-20')); // true console.log(pattern7.test('2016/08/20')); // false
// 挑战八:时间格式:小时:分钟,24小时制 var pattern8 = null; // 补全该正则表达式 console.log(pattern8.test('13:45')); // true console.log(pattern8.test('13点45')); // false
// 挑战九:中国大陆身份证号,15位或18位 var pattern9 = null; // 补全该正则表达式 console.log(pattern9.test('4223222199901090033')); // true console.log(pattern9.test('asdfasdfasfasdf1234')); // false
更多
关注微信公众号「劼哥舍」回复「答案」,获取关卡详解。
关注 https://github.com/stone0090/javascript-lessons,获取最新动态。
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!