javascript -- js正则表达式

正则表达式可以: 

1、测试字符串的某个模式。例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式。这称为数据有效性验证

2、替换文本。可以在文档中使用一个正则表达式来标识特定文字,然后可以全部将其删除,或者替换为别的文字 

3、根据模式匹配从字符串中提取一个子字符串。可以用来在文本或输入字段中查找特定文字 

 

正则表达式语法

一个正则表达式就是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。 

 

1、正则表达式的创建

   1)直接量创建法:

       var pattern=/s$/i; 

       像字符串的创建可以用一对引号一样,正则表达式的创建则可以用一对斜杠号(//)

   2)对象创建法:

     var pattern=new RegExp(“s$”,"i");    //这个式子与上面那个事等价的

       正如字符串可以通过String对象来创建一样,正则表达式也可以通过RegExp对象来创建。

  g (全文查找) 
  i (忽略大小写) 
  m (多行查找)

 

2、字符类

       将单独的直接量字符放进方括号内就可以组合成字符类,一个字符类和它所包含的任何字符都匹配,所以正则表达式/[abc]/和字母a、b、c中的任意一个都匹配。

      另外还可以定义否定字符类,这些类匹配的是不包含在方括号内的任意一个字符。定义否定字符类的时候要将一个^符号作为方括号内的第一个字符,如/[^abc]/匹配的是除字母a、b、c 以外的任何字符。

      字符类可以用连字符来表示一个字符范围,例如要匹配任何数字可以使用/[0-9]/,其相当于/[0123456789]/,要匹配任意的小写字母可使用/[a-z]/,要匹配任何大写字母可使用/[A-Z]/,要匹配任意数字和字母可使用/[a-zA-Z0-9]/

 

3、预定义类

.

除了换行和回车之外的任意字符

\d

数字

\D

非数字

\w

字母

\W

非字母

\s

空白字符

\S

非空白字符

 \n 

换行符

\r

回车符 

\t

制表符

\f

 换页符(Tab)

\cX

与X对应的控制字符

\b

退格符(BackSpace) 

\v

垂直制表符 

\0

 空字符("") 

 
 

3、重复(简单量词)

      指定重复的字符出现在它们所作用的模式之后

      {n,m}   匹配前一项至少n次,但是不能超过m次,即n<=匹配次数<=m

      {n,}     匹配前一项至少n次,  即n<=匹配次数

      {n}      匹配前一项恰好n次,  即n=匹配次数

       ?        匹配前一项0次或1次

       +         匹配前一项至少一次

       *         匹配前一项0次或多次

       /\d{2,4}/  匹配一个2位数、3位数或4位数

      /\w{3}\d?/  匹配3个字符或3个字符加一个数字  

注意:在使用?和*时要注意,由于它们都可以匹配0次,所以它们允许什么都不匹配,例如/a*/实际上与字符串”bbbb”是匹配的,因为它含有0个a

 

贪婪、惰性、和支配性的量词:

  在简单的量词后加一个号,表示的是惰性匹配,如xxx?;

  不加则表示贪婪匹配;

  加一个+则表示整个字符串匹配,如xxx+

 

  贪婪匹配从后向前的,方式是从0个开始,逐个删除末尾字符,直到匹配成功或字符全部删除完。

  惰性匹配从前向后,方式是从1个开始,逐个字符增加的读取字符串,直到匹配成功。

  支配量词则是与整个字符串进行匹配

贪婪匹配 惰性匹配 匹配描述
? ?? 匹配 0 个或 1 个
+ +? 匹配 1 个或多个
* *? 匹配 0 个或多个
{n} {n}? 匹配 n 个
{n,m} {n,m}? 匹配 n 个或 m 个
{n,} {n,}? 匹配 n 个或多个

 

4、字符“|”用于分隔供选择的字符

     例如/ab|cd|ef/ 匹配的是ab或cd或ef

          /\d{3}|[a-z]{4}/ 匹配的是3个数字或4个小写字母

  注意:选择项是从左到右考虑,一旦发现了匹配项就会停止匹配,即使后面还有匹配项

 

5、括号的作用

  1)把单独的项目组合成子表达式,以便可以像处理一个独立的单元那样使用|、*、+、?等符号来处理他们,例如:

       /java(script)?/ 可以匹配java 也可以匹配 javascript

       /(ab|cd)+|ef/ 匹配的是ab或cd或ef 

2)我们可以在正则表达式的后部引用前面括号内表达式所匹配的内容,这个内容要在进行具体匹配时才能确定。 引用的方法是通过在“\”后加一位数字或多位数字来实现的,数字指定了带括号的字表达式在正则表达式中的位置,例如\1引用的是第一个代括号的子表达式的匹配内容,\2引用的是第二个,如果有括号嵌套的情况发生,则不要管嵌不嵌套,直接从左边数起,看看要引用的带括号的字表达式的左边括号在所有左边括号中所处的位置。例如(a(b)(a)),要引用(a) 则使用 \3

正则表达式相关的方法和属性

正则表达式对象的方法

test,返回一个 Boolean 值,它指出在被查找的字符串中是否存在模式。如果存在则返回 true,否则就返回 false。 

exec,用正则表达式模式在字符串中运行查找,并返回包<script type="text/javascript" src="http://www.javaeye.com/javascripts/tinymce/themes/advanced/langs/zh.js"></script><script type="text/javascript" src="http://www.javaeye.com/javascripts/tinymce/plugins/javaeye/langs/zh.js"></script>含该查找结果的一个数组。 

compile,把正则表达式编译为内部格式,从而执行得更快。

 

正则表达式对象的属性 
source,返回正则表达式模式的文本的复本。只读。

lastIndex,返回字符位置,它是被查找字符串中下一次成功匹配的开始位置。

$1...$9,返回九个在模式匹配期间找到的、最近保存的部分。只读。

input ($_),返回执行规范表述查找的字符串。只读。

lastMatch ($&),返回任何正则表达式搜索过程中的最后匹配的字符。只读。

lastParen ($+),如果有的话,返回任何正则表达式查找过程中最后括的子匹配。只读。

leftContext ($`),返回被查找的字符串中从字符串开始位置到最后匹配之前的位置之间的字符。只读。

rightContext ($'),返回被搜索的字符串中从最后一个匹配位置开始到字符串结尾之间的字符。只读。

 

String对象一些和正则表达式相关的方法

match,找到一个或多个正则表达式的匹配。

replace,替换与正则表达式匹配的子串。

search,检索与正则表达式相匹配的值。

split,把字符串分割为字符串数组。 

//test方法,测试字符串,符合模式时返回true,否则返回false 
var re = /he/;//最简单的正则表达式,将匹配he这个单词 
var str = "he"; 
alert(re.test(str));//true 
str = "we"; 
alert(re.test(str));//false 
str = "HE"; 
alert(re.test(str));//false,大写,如果要大小写都匹配可以指定i标志(i是ignoreCase或case-insensitive的表示) 
re = /he/i; 
alert(re.test(str));//true 
str = "Certainly!He loves her!"; 
alert(re.test(str));//true,只要包含he(HE)就符合,如果要只是he或HE,不能有其它字符,则可使用^和$ 
re = /^he/i;//脱字符(^)代表字符开始位置 
alert(re.test(str));//false,因为he不在str最开始 
str = "He is a good boy!"; 
alert(re.test(str));//true,He是字符开始位置,还需要使用$ 
re = /^he$/i;//$表示字符结束位置 
alert(re.test(str));//false 
str = "He"; 
alert(re.test(str));//true 
//当然,这样不能发现正则表达式有多强大,因为我们完全可以在上面的例子中使用==或indexOf 
re = /\s/;  // \s匹配任何空白字符,包括空格、制表符、换页符等等 
str= "user Name";//用户名包含空格 
alert(re.test(str));//true 
str = "user Name";//用户名包含制表符 
alert(re.test(str));//true 
re=/^[a-z]/i;  //[]匹配指定范围内的任意字符,这里将匹配英文字母,不区分大小写 
str="variableName";//变量名必须以字母开头 
alert(re.test(str));//true 
str="123abc"; 
alert(re.test(str));//false

 

当然,仅仅知道了字符串是否匹配模式还不够,我们还需要知道哪些字符匹配了模式 

var osVersion = "Ubuntu 8";//其中的8表示系统主版本号 
var re = /^[a-z]+\s+\d+$/i; //+号表示字符至少要出现1次,\s表示空白字符,\d表示一个数字 
alert(re.test(osVersion));//true,但我们想知道主版本号 
//另一个方法exec,返回一个数组,数组的第一个元素为完整的匹配内容 
re=/^[a-z]+\s+\d+$/i; 
arr = re.exec(osVersion); 
alert(arr[0]);//将osVersion完整输出,因为整个字符串刚好匹配re 
//我只需要取出数字 
re=/\d+/; 
var arr = re.exec(osVersion); 
alert(arr[0]);//8

 


更复杂的用法,使用子匹配 

//exec返回的数组第1到n元素中包含的是匹配中出现的任意一个子匹配 
re=/^[a-z]+\s+(\d+)$/i;  //用()来创建子匹配 
arr =re.exec(osVersion); 
alert(arr[0]);//整个osVersion,也就是正则表达式的完整匹配 
alert(arr[1]);//8,第一个子匹配,事实也可以这样取出主版本号 
alert(arr.length);//2 
osVersion = "Ubuntu 8.10";//取出主版本号和次版本号 
re = /^[a-z]+\s+(\d+)\.(\d+)$/i;  //.是正则表达式元字符之一,若要用它的字面意义须转义 
arr = re.exec(osVersion); 
alert(arr[0]);//完整的osVersion 
alert(arr[1]);//8 
alert(arr[2]);//10

 


注意,当字符串不匹配re时,exec方法将返回null 
String对象的一些和正则表达式有关的方法 

//replace方法,用于替换字符串 
var str ="some money"; 
alert(str.replace("some","much"));//much money 
//replace的第一个参数可以为正则表达式 
var re = /\s/;//空白字符 
alert(str.replace(re,"%"));//some%money 
//在不知道字符串中有多少空白字符时,正则表达式极为方便 
str ="some some \tsome\t\f"; 
re = /\s+/; 
alert(str.replace(re,"#"));//但这样只会将第一次出现的一堆空白字符替换掉 
//因为一个正则表达式只能进行一次匹配,\s+匹配了第一个空格后就退出了 
re = /\s+/g;//g,全局标志,将使正则表达式匹配整个字符串 
alert(str.replace(re,"@"));//some@some@some@ 
var str = "ADF9DF9DF9", //那个文本文件中的字符串; 
re = /9/gi, //匹配9 
counter = 0; //计数器 var newstr = 
str = str.replace(re, function() { 
counter++; //每出现一次匹配,函数就被执行一次,函数的返回值用来替换原值 
return "#"; 
}); 
alert("替换次数: "+counter); 
//alert(str); 
//最后str 变成 ADF#DF#DF#" 
var str = "他今年22岁,她今年20岁,他的爸爸今年45岁,她的爸爸今年44岁,一共有4人" 
function test($1) { 
var gyear = (new Date()).getYear() - parseInt($1) + 1; 
return $1 + "(" + gyear + "年出生)"; 
} 
// var reg = new RegExp("(http://www.cnblogs.com/sgivee/admin/file://d/+)岁", "g"); 
var reg = /(\d+)岁/gi; 
var newstr = str.replace(reg, test); 
//alert(str); 
//alert(newstr); 
//另一个与之相似的是split 
var str = "a-bd-c"; 
var arr = str.split("-");//返回["a","bd","c"] 
//如果str是用户输入的,他可能输入a-bd-c也可能输入a bd c或a_bd_c,但不会是abdc(这样就说他输错了) 
str = "a_db-c";//用户以他喜欢的方式加分隔符s 
re=/[^a-z]/i;//前面我们说^表示字符开始,但在[]里它表示一个负字符集 
//匹配任何不在指定范围内的任意字符,这里将匹配除字母处的所有字符 
arr = str.split(re);//仍返回["a","bd","c"]; 
//在字符串中查找时我们常用indexOf,与之对应用于正则查找的方法是search 
str = "My age is 18.Golden age!";//年龄不是一定的,我们用indexOf不能查找它的位置 
re = /\d+/; 
alert(str.search(re));//返回查找到的字符串开始下标10 
//注意,因为查找本身就是出现第一次就立即返回,所以无需在search时使用g标志 
//下面的代码虽然不出错,但g标志是多余的 
re=/\d+/g; 
alert(str.search(re));//仍然是10

 


类似于exec方法,String对象的match方法也用于将字符串与正则表达式进行匹配并返回结果数组 

var str = "My name is CJ.Hello everyone!"; 
var re = /[A-Z]/;//匹配所有大写字母 
var arr = str.match(re);//返回数组 
alert(arr);//数组中只会包含一个M,因为我们没有使用全局匹配 
re = /[A-Z]/g; 
arr = str.match(re); 
alert(arr);//M,C,J,H 
//从字符串中抽取单词 
re = /\b[a-z]*\b/gi;//\b表示单词边界 
str = "one two three four"; 
alert(str.match(re));//one,two,three,four

 


RegExp对象实例的一些属性 

var re = /[a-z]/i; 
alert(re.source);//将[a-z]字符串输出 
//请注意,直接alert(re)会将正则表达式连同前向斜线与标志输出,这是re.toString方法定义的

var re = /[a-z]/i; 
alert(re.source); 
//将[a-z]字符串输出 
//请注意,直接alert(re)会将正则表达式连同前向斜线与标志输出,这是re.toString方法定义的 
每个RegExp对象的实例具有lastIndex属性,它是被查找字符串中下一次成功匹配的开始位置,默认值是-1。 lastIndex 属性被 RegExp 对象的 exec 和 test 方法修改.并且它是可写的. 

复制代码 代码如下:

var re = /[A-Z]/; 
//exec方法执行后,修改了re的lastIndex属性, 
var str = "Hello,World!!!"; 
var arr = re.exec(str); 
alert(re.lastIndex);//0,因为没有设置全局标志 
re = /[A-Z]/g; 
arr = re.exec(str); 
alert(re.lastIndex);//1 
arr = re.exec(str); 
alert(re.lastIndex);//7

 


当匹配失败(后面没有匹配),或lastIndex值大于字符串长度时,再执行exec等方法会将lastIndex设为0(开始位置) 

var re = /[A-Z]/; 
var str = "Hello,World!!!"; 
re.lastIndex = 120; 
var arr = re.exec(str); 
alert(re.lastIndex);//0

 


RegExp对象的静态属性 

//input 最后用于匹配的字符串(传递给test,exec方法的字符串) 
var re = /[A-Z]/; 
var str = "Hello,World!!!"; 
var arr = re.exec(str); 
alert(RegExp.input);//Hello,World!!! 
re.exec("tempstr"); 
alert(RegExp.input);//仍然是Hello,World!!!,因为tempstr不匹配 
//lastMatch 最后匹配的字符 
re = /[a-z]/g; 
str = "hi"; 
re.test(str); 
alert(RegExp.lastMatch);//h 
re.test(str); 
alert(RegExp["$&"]);//i ,$&是lastMatch的短名字,但由于它不是合法变量名,所以要。。 
//lastParen 最后匹配的分组 
re = /[a-z](\d+)/gi; 
str = "Class1 Class2 Class3"; 
re.test(str); 
alert(RegExp.lastParen);//1 
re.test(str); 
alert(RegExp["$+"]);//2 
//leftContext 返回被查找的字符串中从字符串开始位置到最后匹配之前的位置之间的字符 
//rigthContext 返回被搜索的字符串中从最后一个匹配位置开始到字符串结尾之间的字符 
re = /[A-Z]/g; 
str = "123ABC456"; 
re.test(str); 
alert(RegExp.leftContext);//123 
alert(RegExp.rightContext);//BC456 
re.test(str); 
alert(RegExp["$`"]);//123A 
alert(RegExp["$'"]);//C456

 


multiline属性返回正则表达式是否使用多行模式,这个属性不针对某个正则表达式实例,而是针对所有正则表达式,并且这个属性可写.(IE与Opera不支持这个属性) 

alert(RegExp.multiline); 
//因为IE,Opera不支持这个属性,所以最好还是单独指定 
var re = /\w+/m; 
alert(re.multiline); 
alert(RegExp["$*"]);//RegExp对象的静态属性不会因为给RegExp某个对象实例指定了m标志而改变 
RegExp.multiline = true;//这将打开所有正则表达式实例的多行匹配模式 
alert(RegExp.multiline);

 


使用元字符注意事项:元字符是正则表达式的一部分,当我们要匹配正则表达式本身时,必须对这些元字符转义.下面是正则表达式用到的所有元字符 
( [ { \ ^ $ | ) ? * + . 

var str = "?"; 
var re = /?/; 
alert(re.test(str));//出错,因为?是元字符,必须转义 
re = /\?/; 
alert(re.test(str));//true

 

使用RegExp构造函数与使用正则表达式字面量创建正则表达式注意点 

var str = "\?"; 
alert(str);//只会输出? 
var re = /\?/;//将匹配? 
alert(re.test(str));//true 
re = new RegExp("\?");//出错,因为这相当于re = /\?/ 
re = new RegExp("\\?");//正确,将匹配? 
alert(re.test(str));//true

 

既然双重转义这么不友好,所以还是用正则表达式字面量的声明方式 
如何在正则表达式中使用特殊字符? 

//ASCII方式用十六进制数来表示特殊字符 
var re = /^\x43\x4A$/;//将匹配CJ 
alert(re.test("CJ"));//true 
//也可使用八进制方式 
re = /^\103\112$/;//将匹配CJ 
alert(re.test("CJ"));//true 
//还可以使用Unicode编码 
re =/^\u0043\u004A$/;//使用 Unicode,必须使用u开头,接着是字符编码的四位16进制表现形式 
alert(re.test("CJ"));

 


字符类 ---〉简单类,反向类,范围类,组合类,预定义类

//简单类 
var re = /[abc123]/;//将匹配abc123这6个字符中一个 
//负向类 
re = /[^abc]/;//将匹配除abc之外的一个字符 
//范围类 
re = /[a-b]/;//将匹配小写a-b 26个字母 
re = /[^0-9]/;//将匹配除0-9 10个字符之处的一个字符 
//组合类 
re = /[a-b0-9A-Z_]/;//将匹配字母,数字和下划线

 

var str = "abc"; 
var re = /\w+/;//将匹配abc 
re = /\w+?/;//将匹配a


多行模式

var re = /[a-z]$/; 
var str = "ab\ncdef"; 
alert(str.replace(re,"#"));//ab\ncde# 
re =/[a-z]$/m; 
alert(str.replace(re,"#"));//a#\ncde#

 

分组与非捕获性分组

re = /abc{2}/;//将匹配abcc 
re = /(abc){2}/;//将匹配abcabc 
//上面的分组都是捕获性分组 
str = "abcabc ###"; 
arr = re.exec(str); 
alert(arr[1]);//abc 
//非捕获性分组 (?:) 
re = /(?:abc){2}/; 
arr = re.exec(str); 
alert(arr[1]);//undefined

 


候选(也就是所说的“或”)

re = /^a|bc$/;//将匹配开始位置的a或结束位置的bc 
str ="add"; 
alert(re.test(str));//true 
re = /^(a|bc)$/;//将匹配a或bc 
str ="bc"; 
alert(re.test(str));//true

 

当包含分组的正则表达式进行过test,match,search这些方法之后,每个分组都被放在一个特殊的地方以备将来使用,这些存储是分组中的特殊值,我们称之为反向引用 
Js代码

var re = /(A?(B?(C?)))/; 
/*上面的正则表达式将依次产生三个分组 
(A?(B?(C?))) 最外面的 
(B?(C?)) 
(C?)*/ 
str = "ABC"; 
re.test(str);//反向引用被存储在RegExp对象的静态属性$1—$9中 
alert(RegExp.$1+"\n"+RegExp.$2+"\n"+RegExp.$3); 
//反向引用也可以在正则表达式中使用\1 ,\2...这类的形式使用 
re = /\d+(\D)\d+\1\d+/; 
str = "2008-1-1"; 
alert(re.test(str));//true 
str = "2008-4_3"; 
alert(re.test(str));//false

 


使用反向引用可以要求字符串中某几个位置上的字符必须相同.另外,在replace这类方法中可用特殊字符序列来表示反向引用 
Js代码

re = /(\d)\s(\d)/; 
str = "1234 5678"; 
alert(str.replace(re,"$2 $1"));//在这个里面$1表示第一个分组1234,$2则表示5678

 


其它——〉正向前瞻,用来捕获出现在特定字符之前的字符,只有当字符后面跟着某个特定字符才去捕获它。与正向前瞻对应的有负向前瞻,它用匹配只有当字符后面不跟着某个特定字符时才去匹配它。在执行前瞻和负向前瞻之类的运算时,正则表达式引擎会留意字符串后面的部分,然而却不移动index 
Js代码

//正向前瞻 
re = /([a-z]+(?=\d))/i; 
//我们要匹配后面跟一个数字的单词,然后将单词返回,而不要返回数字 
str = "abc every1 abc"; 
alert(re.test(str));//true 
alert(RegExp.$1);//every 
alert(re.lastIndex);//使用前瞻的好处是,前瞻的内容(?=\d)并不会当成一次匹配,下次匹配仍从它开始 
//负向前瞻(?!) 
re = /([a-z](?!\d))/;i 
//将匹配后面不包含数字的字母,并且不会返回(?!\d)中的内容 
str = "abc1 one"; 
alert(re.test(str)); 
alert(RegExp.$1);//one

 


构建一个验证电子邮箱地址有效性的正则表达式。电子邮箱地址有效性要求(我们姑且这样定义):用户名只能包含字母数字以及下划线,最少一位,最多25位,用户名后面紧跟@,后面是域名,域名名称要求只能包含字母数字和减号(-),并且不能以减号开头或结尾,然后后面是域名后缀(可以有多个),域名后缀必须是点号连上2-4位英文字母 
Js代码

var re = /^\w{1,15}(?:@(?!-))(?:(?:[a-z0-9-]*)(?:[a-z0-9](?!-))(?:\.(?!-)))+[a-z]{2,4}$/;  

 

posted @ 2015-05-27 14:24  goodup  阅读(568)  评论(0编辑  收藏  举报

如有不对之处,欢迎指出,一起成长