可能是最简单的正则教程
为什么要学正则表达式虽然很多web开发者在忽视正则表达式后,还可以顺利工作,但在javascript中还存在一些问题,如果不用正则表达式,是没办法进行很好的解决的. 当然,也许还有其他的方式能够解决相同的问题.但通常,用一句正确的正则表达式很有可能就可以省略半屏幕的代码. 为什么正则表达式很牛假设我们要验证一个字符串是否为格式正确的手机号码.手机号码开头都是1,然后后面都是数字,然后长度都为11位 function isPhoneNumber(candidate){ if(typeof candidate !== "string" || candidate.length!=11){ return false; //过滤明显不符合条件的输入内容 } if(isNaN(candidate)){ return false; //过滤非纯数字的输入内容 } return true; } 虽然这段代码实现的很合理,检查了输入内容的类型和长度,但是对于一个简单的手机号码检查,看起来依然有太多的代码 function isPhoneNumber(candidate){ return /^1[0-9]{10}$/.test(candidate) } 除了函数体内的一些深奥的语法以外,这种方式看起来更简洁,更优雅,不是吗? 正则表达式进阶让我们开始对正则表达式进行深挖,要学习正则表达式,就先了解正则表达式出现的由来 正则表达式解释"正则表达式(regular expression)" 这个词源于中世纪的数学,当时,一个名叫Stephen Kleene的数学家,使用了一个名为"正则集合"的数学符号描述自动计算模式.但这不会帮助我们了解任何关于正则表达式的内容,那么让我们把它简单化,正则表达式通常被称为一个模式(pattern),是一个用简单方式描述或者匹配一系列符合某个语法规则的字符串.表达式本身包含了允许定义这些模式的术语和操作符.我们很快就会看到这些术语和操作符. 在 javascript 中,与大多数其他对象类型一样,有两种方式可以创建正则表达式:通过正则表达式字面量,或者通过构造 RegExp 对象的实例. 例如,如果要创建一个正则表达式 (或简称为正则(regex)),用于精确匹配字符串 "test",可以使用正则字面量: var pattern = /test/; 正斜杠可能看起来有点奇怪,但是就像字符串使用引号进行界定的一样,正则字面量是用正斜杠进行界定的. 或者,我们可以构造一个 RegExp 实例,将正则作为字符串传入: var pattern = new RexExp('test'); 这两种格式在pattern变量中创建的正则表达式都是一样的. 在开发过程中,如果正则是已知的,则优先选择字面量语法,而构造器方式则是用于在运行时,通过动态创建字符串来构建正则表达式. 字面量语法优先于用字符串构建正则表达式的其中一个原因是反斜杠字符在正则表达式中发挥重要的作用(很快就能看到).但由于反斜杠字符在普通字符串中也是一个转义字符,所以,如果要在字符串内表示反斜杠,我们就要使用 除了表达本身,还有三个标志可以与正则表达式进行关联.
这些标志将附加到字面量尾部(例如: RegExp 对象方法
例子:
需要注意的是String对象也有个match方法,也可以检索目标字符串,用法和RegExp的exec方法类似,区别是
参考资料:http://www.aspzz.cn/article/46374.htm ? 术语与操作符正则表达式,就像我们熟悉的大多数其他表达式一样,由术语和验证这些术语的操作符组成.在接下来的小节中,我们将了解这些术语和操作符,看看它们是如何用于表达模式的. 精确匹配如果一个字符不是特殊字符或操作符(后续会进行介绍),则表示该字符必须在表达式中出现.例如,在 一个接一个的字符,隐式表达了"后面跟着(followed by)"这样一个操作.所以, 匹配一类字符很多时候,我们并不像匹配一个特定的字符,而是想匹配一个有限字符集中的某一个字符.我们可以通过将字符集放到中括号内,来指定该字符集操作符(也被称为字符类(character class)操作符): 上述示例,是说我们要匹配 "a" "b" "c" 中的任何一个字符. 有的时候,我们想要匹配一组有限字符集以外的字符.可以通过在中括号第一个开括号后面加一个插入符(^)来实现,比如:
其意义将改变为:除了 "a" "b" 或 "c" 以外的任意字符. 在字符集操作方面,还有一个更加重要的变异操作: 指定一个范围. 例如,如果要匹配 "a" 和 "m" 之间的任何一个小写字母,我们可以这样写: 中横线表示从 "a" 到 "m" 之间的所有字符 (包含 a 和 m,按字典顺序)都在该字符集内. 转义并不是所有的字符和其字符字面量都是等价的.当然,所有的字母和十进制数字字符都能代表自己,但是,我们很快就会发现.像$ 和点(.) 这样的特殊字符,表示的是他们自身以外的东西,或者表示为验证术语的操作符. 事实上,我们已经看到了如何用 如果我们需要匹配[、]、$、^或其他这样的特殊字符,该怎么办?在正则里,使用反斜杠可以对任意字符进行转义,让被转义字符作为字符本身进行匹配.所以, 匹配开始于匹配结束我们可能经常需要确保模式匹配一个字符串的开始,或者一个字符串的结束.插入符号(^),如果作为正则表达式的第一个字符,则表示要从字符串的开头进行匹配,这样 类似的,美元符号$表示该模式必须出现在字符串的结尾: 同时使用^和$则表明指定的模式必须包含整个候选字符串. 重复出现如果要匹配连续的4个 "a" 字符,可以用 在重复选项上,正则表达式提供了很多方式.
这些重复操作符可以是贪婪的(greedy)或非贪婪的(nongreedy).默认情况下,它们是贪婪的:它们匹配所有的字符组合.在操作符后面加一个问号?字符(?操作符的一个重载),如 a+?,可以让该表达式变成非贪婪的:进行最小限度的匹配 举个例子,如果我们对字符串 "aaa" 进行匹配,正则表达式 预定义字符类有一些我们想匹配的字符,是不可能用字面量字符来表示的(如像回车的控制字符),还有一些我们可能经常想匹配的字符类,比如小数位数或一组空白字符.正则表达式语法提供了很多表示这些字符或常用类的预定义术语,这样在正则表达式中,我们就可以使用这些控制字符进行匹配了,因此,我们不需要再去依靠常用的字符集. 下面列出了这些术语以及它们表示的字符或字符集.
这些预定义集,让正则表达式看起来不那么过于神秘了. 分组到目前为止,我们看到的操作符(如+和*)只能影响前面的术语.如果将操作符应用于一组术语,可以像数学表达式一样在该组上使用小括号.例如, 当正则表达式有一部分使用括号进行分组时,它具有双重责任,同时也创建所谓的捕获(capture).正则表达式有很多捕获,我们将在下面对其进行更深入的讨论. 或操作符(OR)可以用竖线(|)字符表示或者的关系.例如: 反向引用正则表达式中最复杂的术语是在正则中所定义的捕获(captures)的反向引用,我们将在后面几节花很大篇幅来介绍捕获方面的内容,但现在就将捕获作为正则表达式中能够成功匹配术语时的候选字符串. 这种术语表示法是在反斜杠后面加一个要引用的捕获数量,该数字从1开始,如 举例来说,
要匹配像 " whatever" 这样的元素,不适用反向引用,是无法做到的,因为我们无法知道关闭标签和开始标签是否匹配. 例如:
正则在线测试 在上面的代码中,我们使用 还有一个方法可以获取捕捉的引用,那就是通过调用String对象的replace()方法替换字符串.在这里,我们使用 例子: var pattern=/([A-Z])/g; var str="fontFamily"; console.log(str.replace(pattern,"-$1").toLowerCase()); //font-family 在上面的代码中,首先获取的捕获值(在本例中是大写字母F),在替换字符串中进行了引用(通过$1).这种方式允许我们制定一个替换字符串,即便是在运行之前还不知道它的值.这是个强大的武器. 这种可以引用正则表达式捕捉结果的能力,让很多本来很复杂困难的代码变得相当简单.其富有表现力的特性,将本来可能很迟钝,复杂且冗长的代码,最终变成了一些简短的语句. 分组与捕获有时候我们需要在一个字符串里找到特定的数据,比如需要在爬虫爬到的数据里找到特定的数据,比如天气温度,用户id,特定标签里面的内容.拿在特定标签里找里面的内容来举例,用正则匹配的话我们通常会先找到这个标签,比如
我们找到了strong标签和它里面的内容,那么又怎么找到strong标签里面的test呢? 其实,只需要给''.+''加个括号就行
于是我们看到匹配内容多了个test 由于返回的匹配是个数组,所以我们只需要用数组下标就能取到test这个值
为什么加个括号就能取到test了呢 ? 我们前面已经知道了小括号具有双重责任,不仅可以用来分组,还会创建所谓的 "捕获" . 因此,使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。 既然小括号既有分组的作用,又有捕获的作用,如果我们只想分组,又不想捕获怎么办呢? 思考一下如下的正则表达式: var pattern=/((good-)+)man/; 在单词 "man" 前面,允许前缀 "good" 出现一次或多次,并且希望捕获整个前缀.这个正则表达式需要两层括号
一切运行正常,但由于括号分组的功能,不仅是单一目标捕获 要让一组括号不进行结果捕获,正则表达式的语法允许我们在开始括号后加一个 将我们的正则表达式修改成如下这样: var pattern=/((?:good-)+)man/; 该表达式只会为外层的括号创建捕获.内层括号被转换为一个被动子表达式 利用函数进行替换String的replace()方法是一个强大且灵活的方法,将正则表达式作为replace()方法的第一个参数时,导致在该模式的匹配元素(全局匹配的话,就是多个匹配元素)上进行替换,而不是在固定字符串上进行替换. 举个例子,假如需要让所有的大写字符串都替换成"X",我们可以这样编写: "ABCEDfg".replace(/[A-Z]/g,"X") 其结果为 "XXXXXfg". 很不错. 不过,获取replace()最强大的特性是可以接受一个函数作为替换值,而不是一个固定的字符串. 当替换值(第二个参数)是一个函数时,每个匹配都会调用该函数(记住,全局搜索会在源字符串中匹配所有的模式实例)并带有一串参数列表.
函数的返回值是即将要替换掉值. 这给了我们很多思考的余地,让我们在运行时确定应该替换的字符串,并掌握大量与匹配特性有关的信息. 例如,在下面的代码中,我们使用一个函数,动态地将中横线分割的字符转换成等价的驼峰拼写字符. function upper(all,letter){ return letter.toUpperCase(); } var pattern=/-(w)(w)/g; var str="border-bottom-width"; console.log(str.replace(pattern,upper)); //borderBttomWdth 在这里,我们提供了一个正则表达式,用于匹配中横线字符后的任意一个字符.全局正则中的捕获结果就是该匹配的字符(不包括之中横线).函数在每次被调用的时候(本例中是两次),传入匹配的完整的字符串作为第一个参数,捕获结果(本例只有一个)作为第二个参数.我们对其他参数不感兴趣,所以没有指定他们. 函数在第一次被调用的时候,传入了 "-b" 和 "b",第二次被调用的时候传入的是 "-w" 和 "w",将捕获字符转换成大写,并作为替换值返回.最终,我们将 "-b" 替换成了 "B",将 "-w" 替换成了 "W" 利用正则表达式解决常见问题修剪字符串将字符串前后多余的空格进行删除是一种常见的需求,但String对象却没有这种功能(最近才有).对于没有String.trim()方法的旧版浏览器,几乎所有的JavaScript库都提供了一种实现. 最常用的实现,类似如下代码: function trim(str){ return (str||"").replace(/^s+|s+$/g,""); } console.log(trim(" #id div.class ")==="#id div.class"); //true 参考资料:知道这 20 个正则表达式,能让你少写 1000 行代码 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |