正则表达式看起来很吓人,不容易让人亲近,但它的确很好用,可以很大程度上提高你的开发效率。本文从零开始介绍了应如何学习正则表达式。文中范例主要为JavaScript。

正则表达式可以很恐怖,真得很恐怖。幸运的是,一旦记住每个符号所表达的意思,恐惧就会快速消退。如果你对正则表达式一无所知,正如文章标题,那你又就有很多东西要学了。下面让我们马上开始吧。

基础学习

想要高效地学习和掌握正则表达式的关键是花一天的时间记住所有符号。这可能是我所能提供的最好的建议。坐下来,做些记忆卡片,然后记住它们。以下为最常见的一些符号: 
. - 匹配任意字符,换行符除外(如果 dotall 为 false)。 
* - 该符号前面的字符,匹配 0 次或多次。 
+ - 该符号前面的字符,匹配 1次或多次 
? - 该符号前面的字符是可选的。匹配 0 次或 1 次。 
\d - 匹配任何单个数字。 
\w - 匹配任何一个字符(包括字母数字以及下划线)。 
[XYZ] - 匹配字符组中的任意一个字符,即 X、Y、Z 中的任意一个。 
[XYZ]+ - 匹配字符组中的一个或多个字符。 
$ - 匹配字符串结束的位置。 
^ - 匹配字符串开始的位置。 
[^a-z] - 当出现在字符类中时,^ 表示 NOT(非);对于该示例,表示匹配任何非小写字母。

很闷吧,不过还是记住它们,记住之后你会知道好处的。

工具

你认为一个表达式是正确的,非常正确,但就是无法得到想要的结果,这时你可能会产生将头发拔光的冲动。去下载 RegExr 桌面应用程序吧,这个对你是必不可少的,而且玩起来非常有趣的。它提供实时检查,还有一个侧边栏,里面包含了每个字符的定义和用户,非常详细。

正则表达式和 JavaScript

1. Test()

这个方法接受单个字符串参数,然后返回一个布尔值,该值表明是否找到一个批评。如果你不需要对特定的匹配结果进行操作,比如,验证用户名,“test”方法已足够完成这个任务。

示例

  1. var username = 'JohnSmith';
  2. alert(/[A-Za-z_-]+/.test(username)); // returns true

在上面的代码中,我们首先声明一个正则表达式,表示仅允许大写或小写字母、下划线和连字符。将这些可接受的字符放在括号中,就指定了一个字符组。紧随其后的 + 号表示我们想要正在寻找的是一个或多个前述字符组中的字符。然后使用该范式对变量“JohnSmith”进行测试。由于存在匹配,浏览器的显示框中将显示 true。

2. Split()

你可能对 split 方法已经很熟了。该方法接受单个正规表达式,表示在哪里进行“分割”。请注意,如果喜欢,你还可以使用字符串。

  1. var str = 'this is my string';
  2. alert(str.split(/\s/)); // alerts "this, is, my, string"

上面代码中的 \s 表示单个空格,通过它,我们将字符串分割为一个数组。如果想要访问某个特定的值,使用相应的索引即可。

var str = 'this is my this string';    
alert(str.split(/\s/)[3]); // alerts "string"

3. replace()

可能你已经想到了,replace 方法可以用来将文本中的一部分(由字符串或正则表达式表示)替换为不同的字符串。

示例 
如果想要将“Hello, World”改为“Hello, Universe”,可以使用下面的代码:

  1. var someString = 'Hello, World';
  2. someString = someString.replace(/World/, 'Universe');
  3. alert(someString); // alerts "Hello, Universe"

应留意的是,对于这个简单的示例,我们本来可以简单的使用.replace('World', 'Universe')。另外,使用 replace 方法不会自动重写变量的值,我们必须将返回值再次分配给这个变量:someString。

示例 2 
再举一个例子,假设用户要在我们的网站注册一个账号,我们可能想要提供一些基础的安全预防措施。也许我们想要留下他们的用户名,而删除其他任何符号,引号、分号等等。对于 JavaScript 和正则表达式,执行这类任务是桩琐碎的小事情。

  1. var username = 'J;ohnSmith;@%';
  2. username = username.replace(/[^A-Za-z\d_-]+/, '');
  3. alert(username); // JohnSmith;@%

看到最后生成的显示值,有人可能会想,上面的代码有错误。事实并非如此。你仔细看看,会发现字母“J”后的分号被删除了,正如我们所期望的那样。为了通知引擎继续搜索字符串查找更多匹配,我们可以做结束的斜杠后面直接添加一个“g”,这个修饰符或标记表示“global(全局)”。修改后的代码如下所示:

  1. var username = 'J;ohnSmith;@%';
  2. username = username.replace(/[^A-Za-z\d_-]+/g, '');
  3. alert(username); // alerts JohnSmith

现在,正则表达式搜索整个字符串,替换所有必要的字符。让我们看看关键的表达式(.replace(/[^A-Za-z\d_-]+/g, '');),要注意,括号内的向上箭头(即 ^)非常重要。当放在字符组中时,该符号表示“找到所有不是……”。现在回头在看看这个代码,它表示,找到所有不是字母、数字(由 \d 表示)、下划线或连字符的符号;如果找到一个匹配,将其替换为空,事实上就是删除该字符。

4. Match()

与test方法不同,match() 返回一个包含所有找到的批评的数组。

示例 
var name = 'JeffreyWay';    alert(name.match(/e/)); // alerts "e" 
   上面的代码将显示一个字母“e”。但是,在字符串“JeffreyWay”中实际上包含2个 e。同样,这次我们还是要使用修饰符“g”来声明一个全局搜索。

  1. var name = 'JeffreyWay';
  2. alert(name.match(/e/g)); // alerts "e,e"

如果想要显示数组中这些特定值中的一个,可以做括号中引用想要的索引。

  1. var name = 'JeffreyWay';
  2. alert(name.match(/e/g)[1]); // alerts "e"

示例 2 
让我们看下一个示例,确保我们对它的理解是正确的。

  1. var string = 'This is just a string with some 12345 and some !@#$ mixed in.';
  2. alert(string.match(/[a-z]+/gi)); //alerts "This,is,just,a,string,with,some,and,some,mixed,in"

在这个正则表达式中,我们创建了一个范式,可匹配一个或多个大写或小写字母。这多亏了“i”修饰符。除外,我们还加上了“g”来声明进行全局搜索。上面的代码将显示“This,is,just,a,string,with,some,and,some,mixed,in.”然后,如果想要获取变量数组中这些值中的某一个,我们只需引用相应的索引即可。

  1. var string = 'This is just a string with some 12345 and some !@#$ mixed in.';
  2. var matches = string.match(/[a-z]+/gi);
  3. alert(matches[2]); // alerts "just"   分割电子邮件地址

为了练习,我们试着将一个电子邮件地址(nettuts@tutsplus.com)分割为相应的两部分:用户名和域名,即 nettuts 和tutsplus。

  1. var email = 'nettuts@tutsplus.com';
  2. alert(email.replace(/([a-z\d_-]+)@([a-z\d_-]+)\.[a-z]{2,4}/ig, '$1, $2')); // alerts "nettuts, tutsplus"

如果对于正则表达式,你还是新手,上面的代码可能会看起来有点吓人。不用担心,第一次看到都会感到“恐怖”。一旦将它分解为一个一个小子集,你会发觉其实非常简单。下面让我们一条一条进行分析:

.replace(/([a-z\d_-]+)   从中间开始看,我们要搜索任何字母、数字、下划线或连字符,并且匹配一次或多次(+)。无论匹配是上面,我们想要访问其值,所以将其放到括号中。这样,我们稍后可以引用这个匹配的子集。

@([a-z\d_-]+)   紧接着前一个匹配,我们看到 @ 符号,然后是有一组一个或多个字母、数字、下划线和连字符。同样,我们将其放到括号内,以便稍后访问。

\.[a-z]{2,4}/ig,   继续找,我们看到一个点。因为在正则表达式中,句点可表示任何字符(有时换行符除外),因此必须使用“\”进行转义。最后一部分是用于查找“.com”。我们知道,大多数域名,如果不是所有,其后缀为 2 到 4 个字符(com、edu、net、name 等等)。如果找到具体的范围,我们可以先行使用更常规的符号,如 * 或 +。不过,我们在这里是将2个数字放到一个大括号中,分别表示最大值和最小值。

'$1, $2')   这个最后一部分表示replace方法的第二个参数,或者我们想要将匹配字符集替换为的对象。在这里,我们使用 $1 和 $2 分别来引用保存在第一个和第二个括号中的值。对于这个特定示例, $1 指向 nettuts,$2 指向 tutsplus。

创建自己的位置对象

作为最后的一个项目,我们将创建位置对象。位置对象向用户提供有关当前页面的信息:href、协议、地址、端口等。请注意,这里仅仅是作为练习之用。对于真正的网址,使用已有的位置对象即可。

首先我们创建位置函数,该函数接受单个参数,该参数表示我们想要“解码”的网址,我们将其称为“loc”。

function loc(url) { }   现在,我们可以按照下面的方式调用它,并传入一个乱七八糟的 url:

var l = loc('http://www.somesite.com?somekey=somevalue&anotherkey=anothervalue#theHashGoesHere');

下一步,我们需要返回包含多个方法的对象。

function loc(url) { 
        return {}    
}

搜索(search)

我们不会创建所有方法,但我们会模仿其中几个。第一个是“search”。使用正则表达式,我们将要搜索 url 并返回查询字符串中的所有内容。

  1. return {
  2. search : function() {
  3. return url.match(/\?(.+)/i)[1]; //returns "somekey=somevalue&anotherkey=anothervalue#theHashGoesHere"
  4. }
  5. }

在上面的代码中,我们使用了传入的 url,试图使用我们的正则表达式对其进行匹配。这个正则表达式在整个字符串中搜索问号,问号表示查询字符串(querystring)的开始。在这个位置,我们需奥获取其余的字符,这就是将(.+)放入括号的原因。最后,我们需要返回那个字符区块,因此,使用[1]来定位它。

哈希值(Hash)

现在我们将创建一个方法,返回 url 的哈希值,或者 # 号后面的内容。

  1. hash : function() {
  2. return url.match(/#(.+)/i)[1]; // returns "theHashGoesHere"
  3. },

这次,我们搜索 # 号,同样,使用括号获取后面的字符,并使用 [1] 指向那个特定的子集。

协议

protocol 方法应返回,页面所用的协议,可能你已经猜到了。这种协议通常为 http 或 https。

  1. protocol : function() {
  2. return url.match(/(ht|f)tps?:/i)[0]; //returns 'http:'
  3. },

这一个稍微更加复杂一点,因为存在几个选项:http、https 和 ftp。

虽然可以使用这样的格式 (http|https|ftp),但使用 (ht|f)tps? 更为简洁,表示我们首先查找“ht”或“f”字符,下一步,匹配“tp”字符。最后的“s”是可选的,所以我们加了一个问号,表示问号前的字符出现零次或一次。

Href

这个是最后一个方法,返回页面的 url。

  1. href : function() {
  2. return url.match(/(.+\.[a-z]{2,4})/ig); //returns "http://www.somesite.com"
  3. }

这里,我们对所有字符进行匹配,直到找到一个点号,这个点号后面有 2 - 4 个字符(表示 com、au、edu、name 等等)。重要的是意识到,对于这些表达式,我们可以写得很复杂也可以写得很简单,这在于我们要求有多严格。

一个简单的函数

  1. function loc(url) {
  2. return {
  3. search : function() {
  4. return url.match(/\?(.+)/i)[1];
  5. },
  6. hash : function() {
  7. return url.match(/#(.+)/i)[1];
  8. },
  9. protocol : function() {
  10. return url.match(/(ht|f)tps?:/)[0];
  11. },
  12. href : function() {
  13. return url.match(/(.+\.[a-z]{2,4})/ig);
  14. }
  15. }
  16. }

使用上面这个函数,我们可以很简单地显示网址的每个部分:

  1. var l = loc('http://www.net.tutsplus.edu?key=value#hash');        alert(l.href()); // http://www.net.tutsplus.com
  2. alert(l.protocol());

Javascript正则表达式完全学习手册的更多相关文章

  1. Javascript正则表达式的初步学习

    <html> <head> <meta charset="utf-8"> <title>正则表达式的学习</title> ...

  2. JavaScript正则表达式学习笔记(二) - 打怪升级

    本文接上篇,基础部分相对薄弱的同学请移步<JavaScript正则表达式学习笔记(一) - 理论基础>.上文介绍了8种JavaScript正则表达式的属性,本文还会追加介绍几种JavaSc ...

  3. javascript正则表达式 - 学习笔记

    JavaScript 正则表达式 学习笔记 标签(空格分隔): 基础 JavaScript 正则表达式是用于匹配字符串中字符组合的模式.在javascript中,正则表达式也是对象.这些模式被用于Re ...

  4. Html JavaScript网页制作与开发完全学习手册

    Html JavaScript网页制作与开发完全学习手册 篇 HTML技术章 HTML入门 1.1 什么是HTML 1.1.1 HTML的特点 1.1.2 HTML的历史 1.2 HTML文件的基本结 ...

  5. web前端学习(四)JavaScript学习笔记部分(10)-- JavaScript正则表达式

    1.JavaScript正则表达式课程概要 方便查找字符串.数字.特殊字串等等 2.正则表达式的介绍 RegExp是正则表达式的缩写 当检索某个文本时,可以使用一种模式来描述要检索的内容.RegExp ...

  6. Java Script正则表达式语法学习

    今天在做页面交互验证时,在HTML里面第一反应居然用了Java 处理正则表达式的语法... ---------------------------------题记 学习来源 http://www.ru ...

  7. 理清JavaScript正则表达式--下篇

    紧接:"理清JavaScript正则表达式--上篇". 正则在String类中的应用 类String支持四种利用正则表达式的方法.分别是search.replace.match和s ...

  8. JavaScript正则表达式详解(一)正则表达式入门

    JavaScript正则表达式是很多JavaScript开发人员比较头疼的事情,也很多人不愿意学习,只是必要的时候上网查一下就可以啦~本文中详细的把JavaScript正则表达式的用法进行了列表,希望 ...

  9. (转) 坚持完成这套学习手册,你就可以去 Google 面试了

      坚持完成这套学习手册,你就可以去 Google 面试了 系统 指针 value Google 面试 阅读6138    本文为掘金投稿,译文出自:掘金翻译计划 原文地址:Google Interv ...

随机推荐

  1. 打开jsp页面自动加载多个Action的实现方法

    平时我们加载Action的时候都是提交表单,或者点击按钮以后才能发起Action请求. 现在我要实现一个功能:打开一个网站的首页从数据库中立刻读取多条不同表中的数据显示在页面上.这个时候要发起多个Ac ...

  2. IE6里面display:inlineblock使得块元素成行排列,没用

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  3. Java设计模式--Java Builder模式

    1.Java Builder模式主要是用一个内部类去实例化一个对象,避免一个类出现过多构造函数,而且构造函数如果出现默认参数的话,很容易出错. public Person(String name) P ...

  4. js 中调用 Object.prototype.toString()来检测对象的类型

    1.使用toString()方法来检测对象类型 可以通过toString() 来获取每个对象的类型.为了每个对象都能通过 Object.prototype.toString() 来检测,需要以 Fun ...

  5. egret dragonbones部件替换产生位移的解决方案

    原理:使用Armature.getSlot("urpart").display.texture去替换骨骼纹理即可需要:1 骨骼动画导出的时候不要裁剪部件的透明区域,在导出设置里面设 ...

  6. POJ 2976 Dropping tests 01分数规划 模板

    Dropping tests   Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6373   Accepted: 2198 ...

  7. The 2014 ACM-ICPC Asia Regional Anshan

    继续复盘下一场Regional! [A]-_-/// [B]模拟(之前每次遇到模拟.暴搜都直接跳了,题目太长也是一个原因...下次是在不行可以尝试一下) [C]数论 互质.容斥? [D]数学推导(方差 ...

  8. 转 mybatis javaType与jdbcType对应

    java.sql.Types 值 Java 类型 IBM DB2 Oracle Sybase SQL Informix IBM Content Manager   BIGINT java.lang.l ...

  9. iOS下bound,center和frame

    本文转发至:http://www.xuebuyuan.com/1846606.html 在写程序的时候发现,iOS下的坐标.位置很容易弄乱,特别是在不同的坐标系统中,必须完成弄明白一些概念才能做相应的 ...

  10. eclipse java生成exe

    eclipse导出jar文件再将它转换成exe可执行文件详解 关键字: 欢迎光临 此文章是为了帮助刚接触j2se或不懂如何打包jar文件的人而着笔,同时也是让自己的知识以文章的形式保存起来. 一.导出 ...