Javascript中的正则表达式

刚开始接触正则表达式的时候,觉得这是个很死板的东西(没办法,计算机不能像人眼一样能很快的辨认出我们需要的结果,它需要一定的规则来对它进行限制),了解的越多,发现这个其实很灵活,在我们好多小数据的处理上它都起着很重要的作用,下面,我们再来重新认识它。

创建正则表达式的两种方法:

1.字面量方法

var b=/\bam\b/;
alert( "i am lily".replace(b,'AM')); //i AM lily

2.构造函数方法

var reg=new RegExp(/\bis\b/);
alert("she is beautiful".replace(reg,"is not")); // she is not beautiful

正则表达式匹配模式支持的三个标志

  g:global 全文搜索,不添加则搜索到第一个匹配停止;
  i:ignore case 忽略大小写,默认大小写敏感;
  m:multiple lines 多行搜索

  举例:

/*字面量方法*/
//匹配字符串中所有“at”的实例
var patten1 = /at/g;
//匹配第一个“aat”或“bat”不区分大小写
var patten2 = /at/i;
//匹配所有以“at”结尾的3个字符的组合,不区分大小写
var patten3 = /.at/gi; /*构造函数方法*/
//匹配字符串中所有“at”的实例
var patten1 = new RegExp("at","g");
//匹配第一个“aat”或“bat”不区分大小写
var patten2 = new RegExp("at","i");
//匹配所有以“at”结尾的3个字符的组合,不区分大小写
var patten3 = new RegExp("\.at","gi");

  二者间的区别:

//比较字面量方法和构建函数方法的区别
var re = null,i; for(i=;i<;i++){
re = /cat/g;
re.test("catastrophe");
} for(i=;i<;i++){
re = new RegExp("/cat/","g");
re.test("catastrophe");
}

  在第一个循环中,即使是循环体中指定的,但是实际上只为/cat/创建了一个RegExp实例。由于实例属性不会重置,所以在循环中再次调用test方法会失败。 这是因为第一次调用test找到了“cat”,但是第二次调用的时候是从索引为3的字符开始的,所以就找不到它了。
  在第二个循环中,因为每次迭代都会创建一个新的RegExp实例,所以每次调用test都会返回true。(后面会详细介绍关于test方法)

补充:这个和对象的创建有点相似,因为RegExp本身及时一类特殊的对象,后面我们还会说它具有对象的一些特征。

正则表达式的基本组成

正则表达式由两种基本字符类型组成
   1.原义文本字符:代表它原来含义的字符 例如:abc、123
   2.元字符:在正则表达式中有特殊意义的非字母字符 例如:\b表示匹配单词边界,而非\b
   在正则表达式中具体特殊含义的字符:* + ? $ ^ . \ () {} []
【元字符】

   \t:水平制表符;
   \v:垂直制表符;
   \n:换行符;
   \r:回车符;
   \0:空字符;
   \f:换页符;
   \cX:与X对应的控制字符

正则表达式中的几种常用类

字符类

  一般情况下正则表达式一个字符对应字符串一个字符
  表达式 ab\t 的含义是: 一个字母a一个字母b加一个水平制表符
     可以使用元字符[]来构建一个简单的类,所谓类是指符合某些特征的对象,一个泛指,而不是特指某个字符
       表达式[abc]:把字符 a 或 b 或 c 归为一类,表达式可以匹配这类的字符,即匹配abc中的一个

'a1b2c3d4'.replace(/[abc]/g,'字符');
"字符1字符2字符3d4"

字符类取反

    使用元字符 ^ 创建 反向类/负向类,反向类的意思是:不属于某类的内容
    表达式 [^abc] 表示 不是字符a或b或c 的内容

  'a1b2c3d4'.replace(/[^abc]/g,'字符');
"a字符b字符c字符字符字符"

范围类

  使用字符类匹配数字 [0123456789] 简写[0-9]
    可以使用 [a-z] 来连接两个字符表示 从a到z的任意字符,闭区间,包含a和z本身
    如:

  'a1b2c3zx4z9'.replace(/[a-z]/g,'Q');
"Q1Q2Q3QQ4Q9"

  在[]组成的类内部是可以连写的 [a-zA-Z]
    如:

  'a1b2c3zx4z9ADG'.replace(/[a-zA-Z]/g,'Q');
"Q1Q2Q3QQ4Q9QQQ"

  注意:
   当-在两个字符之间,表示范围,想匹配-,直接在后面加-即可

 '2016-08-08'.replace(/[0-9-]/g,'Q');
"QQQQQQQQQQ"

预定义类

  \D 等价于 [^0-9] 非数字字符
  \s 等价于 [\t\n\x0B\f\r] 空白符 s:space
  \S 等价于 [^\t\n\x0B\f\r] 非空白符
  \w 等价于 [a-zA-Z_0-9] 单词字符(字母、数字下划线) w:word
  \W 等价于 [^a-zA-Z_0-9] 非单词字符
  提示:大写的表示取反
  \b 单词边界
  \B非单词边界
    例子:

1. '@123@abc@'.replace(/^@./g,'Q');
"Q23@abc@"
2.'@123@abc@'.replace(/.@$/g,'Q');
"@123@abQ"
3.'@123@abc@'.replace(/.@/g,'Q');
"@12QabQ"

量词

  ? 出现0次或者一次,最多出现一次。。
  + 出现一次或者多次,至少出现一次。。
  * 出现零次或者多次 可以是任意次数。。
  {n} 出现了n次。
  {n,m} 出现了n到m次。。
  {n,} 至少出现n次。
  如果要表示最多10次,则用{0,10}

贪婪模式和非贪婪模式

贪婪模式(默认)

    正则表达式在匹配时,尽可能多的匹配,直到匹配失败

  '1234568'.replace(/\d{3,6}/g,'Q');
"Q8"

非贪婪模式

  正则表达式尽可能少的匹配,即一旦成功匹配就不再继续匹配
    做法:在量词后加上 ? 即可,例子:

'123456789'.match(/\d{3,5}?/g)
["123", "456", "789"]
    

分组

匹配字符串 Byron 连续出现 3 此的场景
1. 使用()可以达到分组的功能,使量词作用于分组 (Byron){3},如果直接Byron{3}则匹配到的三Byronnn
  例子:小写字母连续出现3次

'a1b2c3d4'.replace(/([a-z]\d){3}/g,'Q');
//"Qd4"

2.  使用 将正则表达式分成前后两部分,可以达到 或 的效果isIS ByronCasper Byr(onCa)sper,例子:

'ByronCasper'.replace(/ByronCasper/g,'Q');
//"Q"
'ByrCasperByronsper'.replace(/Byr(onCa)sper/g,'Q');
//"QQ"

3.反向引用
2015-12-25 => 12/25/2015
在分组的基础上,分组取值使用'$1 $2....'代表捕获分组内容,实现:

'2015-09-09'.replace(/(\d{4})-(\d{2})-(\d{2})/g,'$2/$3/$1');
//"09/09/2015"

忽略分组

不希望捕获某些分组,只需要在分组内加上 ?:即可
(?:Byron).(ok)

'2016-10-06'.replace(/(?:\d{4})-(\d{2})-(\d{2})/g,'$2/$3/$1');
//"06/$3/10"

前瞻

  正则表达式从文本头部向尾部开始解析,文本尾部方向,成为“前”
    前瞻 就是在正则表达式匹配到规则的时候,向前检查是否符合断言。比如找到儿子为张三,还得看看他的父亲是否是李四
    后顾/后瞻方向相反,注意:JavaScript不支持后顾
    符合特定断言称为 肯定/正向 匹配
    不符合特定断言称为 否定/负向 匹配
 
 正向前瞻 exp(?=assert) 先判断是否符合正则,再符合正则的基础上判断是否符合断言
 负向前瞻 exp(?!asseret)

例如:

  \w(?=\d)  正向前瞻 符合断言 匹配单词字符,要求首先是一个单词,并且这个单词符合断言,后跟一个数字
'a2*3'.replace(/\w(?=\d)/g,'A') "A2*3"
'a2*3bb'.replace(/\w(?=\d)/g,'A') "A2*3bb"

RegExp实例属性

    global:是否全文搜索,默认false
    ignore case:是否大小写敏感,默认是false
    multiline:多行搜索,默认值是false
    lastIndex:是当前表达式匹配内容的最后一个字符的下一个位置
    source:正则表达式的文本字符串
    注意: 实例属性是不可以修改的

var pattern1 = /\[bc\]at/;
console.log(pattern1.global); //false
console.log(pattern1.ignoreCase); //false
console.log(pattern1.multiline); //false
console.log(pattern1.lastIndex); //0
console.log(pattern1.source); //\[bc\]at var pattern2 = new RegExp("\\[bc\\]at","i")
console.log(pattern2.global); //false
console.log(pattern2.ignoreCase); //true
console.log(pattern2.multiline); //false
console.log(pattern2.lastIndex); //0
console.log(pattern2.source); //\[bc\]at

正则表达式本身的两个方法

1.test方法

RegExp.prototype.test(str)

  它接受一个字符串参数,用于测试字符串参数中是否存在匹配正则表达式模式的字符串,如果存在则返回true,否则返回false

例子:

var text = "0000-00-00";
var pattern = /\d{4}-\d{2}-\d{2}/;
if(pattern.test(text)){
console.log("the pattern was matched");//the pattern was matched
}

多次执行test()方法,会在true、false之间循环
    (/\w/g).test('a')每次执行都是正确的,但是通过实例化对象,需要很大的开销
    test()方法:原意就是测试有没有、能不能匹配上,当使用test原意时,没必要加g

2.exec方法

RegExp.prototype.exec(str)

  使用正则表达式模式对字符串执行搜索,并将更新全局RegExp对象的属性一反映匹配结果

如果没有匹配的文本则返回 null,否则返回一个结果数组:
     - index 声明匹配文本的第一个字符位置
     - input 存放被检索的字符串 string

vra text = "mom and dad and baby";
var pattern = /mom( and dad( and baby)?)?/gi;
var matches = pattern.exec(text);
console.log(matches.index); //0
console.log(matches.input); //"mom and dad and baby"
console.log(matches[0]); //"mom and dad and baby"
console.log(matches[1]); //" and dad and baby"
console.log(matches[2]); //" and baby"

再如:

var text = "cat, bat, dat, eat";

var pattern1 = /.at/g;
var matches = pattern1.exec(text);
console.log(matches.index); //0
console.log(matches[0]); //cat
console.log(matches.lastIndex); //undefined,(理论上上是3)
matches = pattern1.exec(text);
console.log(matches.index); //5
console.log(matches[0]); //bat
console.log(matches.lastIndex); //undefined,(理论上上是8) var pattern2 = /.at/;
var matches = pattern2.exec(text);
console.log(matches.index); //0
console.log(matches[0]); //cat
console.log(matches.lastIndex); //undefined,(理论上上是0)
matches = pattern2.exec(text);
console.log(matches.index); //0
console.log(matches[0]); //cat
console.log(matches.lastIndex); //undefined,(理论上上是0)

  lastIndex 记录当前匹配结果的、最后一个字符的、下一个字符的位置
    注意:test()方法在匹配的时候当匹配到一个结果时,会从lastIndex位置开始匹配下一个结果,直到不存在的时候才置为0。因此,当使用全局g属性标识时,当匹配到最后一个结果时,lastIndex值指向不存在的位置,此时再执行test()会返回false。

非全局调用
    调用非全局的RegExp对象的 exec()时,返回数组
     第一个元素是与正则表达式相匹配的文本
     第二个元素是与RegExpObject的第一个子表达式相匹配的文本(如果有的话)
     第三个元素是与RegExp对象的第二个子表达式相匹配的文本(如果有的话),以此类推

字符串对象方法

1.search

  String.prototype.search(reg)
  search()方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串
  方法返回第一个匹配结果 index,查找不到返回 -1
  search()并不执行全局匹配,它将忽略标志 g ,并且总是从字符串的开始进行检索
  例子:

'A11B2C3D4'.search(/\d/) //1

2.match

  String.prototype.match(reg)
  match()方法将检索字符串,以找到一个或多个与RegExp匹配的文本
  RegExp是否具有标志 g 对结果影响跟大
  非全局调用,即没有 g
  如果RegExp没有标志 g,那么 match()方法就只能在字符串中执行一次匹配
  如果没有找到任何匹配的文本,将返回null
  否则它将返回一个数组,其中存放了与它找到的匹配文本有关的信息
  返回数组的第一个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本
  除了常规的数组元素之外,返回的数组还含有2个对象属性
  index 声明匹配文本的起始字符在字符串的位置
  input 声明对 stringObject的引用

全局调用

  如果RegExp具有标志 g,则match()方法将执行全局检索,找到字符串中的所有匹配子字符串
  没有找到任何匹配的子串,则返回null
  如果找到了一个或多个匹配的子串,则返回一个数组
  数组元素中存放地字符串中所有的匹配子串,而且也没有index 属性或input属性

var str = 'abc123def456ghi789';
var re = /\d+/g; // 每次匹配至少一个数字 且全局匹配 如果不是全局匹配,当找到数字123,它就会停止了。就只会弹出123.加上全局匹配,就会从开始到结束一直去搜索符合规则的。
console.log( str.match(re) ); // [123,456,789]
//如果没有加号,匹配的结果就是1,2,3,5,4,3,3,8,7,9并不是我们想要的,有了加号,每次匹配的数字就是至少一个了。

3.replace

  String.prototype.replace(str,replaceStr)
  String.prototype.replace(reg,replaceStr)
  String.prototype.replace(reg,function)
  function参数含义
  function会在每次匹配替换的时候调用,有四个参数
  匹配字符串
  正则表达式分组内容,没有分组则没有该参数
  匹配项在字符串中 index
  原字符串

var str = "锄禾日当午,汗滴禾下土。";
var re = /日当午|汗滴/g; // 找到日当午 或者汗滴 全局匹配
var str2 = str.replace(re,'*');
console.log(str2) //锄禾*,*禾下土。 //这种只是把找到的变成了一个*,并不能几个字就对应几个*。

想要把每个汉字都变成*,我们可以用如下办法:

var str = "锄禾日当午,汗滴禾下土。";
var re = /日当午|汗滴/g; // 找到日当午 或者汗滴全局匹配
var str2 = str.replace(re,function(str){
console.log(str); //用来测试:函数的第一个参数代表每次搜索到的符合正则的字符,所以第一次str指的是锄禾 第二次str是日当午 第三次str是汗滴"
var result = '';
for(var i=;i<str.length;i++){
result += '*';
}
return result; //所以搜索到了几个字就返回几个*
});
console.log(str2) //锄禾***,**禾下土。

例子:将2016-10-06变为2016.10.06,代码如下

var str = '2016-10-06';
var re = /(\d+)(-)/g;
str = str.replace(re,function($,$,$){
//replace()中如果有子项,
//第一个参数:$0(匹配成功后的整体结果 2016- 10-),
// 第二个参数 : $1(匹配成功的第一个分组,这里指的是\d 2016, 10)
//第三个参数 : $1(匹配成功的第二个分组,这里指的是- - - )
return $ + '.'; //分别返回2016. 10.
}); alert( str ); //2016.10.06

正则表达式的一些特别用法

1、找重复项最多的字符个数

var str = 'assssjdssskssalsssdkjsssdss';

var arr = str.split(''); //把字符串转换为数组
str = arr.sort().join(''); //首先进行排序,这样结果会把相同的字符放在一起,然后再转换为字符串
//alert(str); // aaddjjkklsssssssssssssssss var value = '';
var index = ;
var re = /(\w)\+/g; //匹配字符,且重复这个字符,重复次数至少一次。
str.replace(re,function($,$){
//alert($0); 代表每次匹配成功的结果 : aa dd jj kk l sssssssssssssssss
//alert($1); 代表每次匹配成功的第一个子项,也就是\w: a d j k l S   
if(index<$.length){ //如果index保存的值小于$0的长度就进行下面的操作
index = $.length; // 这样index一直保存的就在最大的长度
value = $; //value保存的是出现最多的这个字符
}
}); alert('最多的字符:'+value+',重复的次数:'+index); // s 17

2、去掉前后空格

var str = '  hello  ';

console.log(str);	//  hello
alert( '('+trim(str)+')' );//为了看出区别所以加的括号。 (hello) function trim(str){
var re = /^\s+|\s+$/g; // |代表或者 \s代表空格 +至少一个 前面有至少一个空格 或者后面有至少一个空格 且全局匹配
return str.replace(re,''); //把空格替换成空
}

 3、其他

  还有很多正则表达式的用法,主要在表单验证上。比如说手机号码验证,身份证号码验证,邮箱验证等。在这里,推荐两个比较实用的网站:

  正则表达式调试工具:http://www1.w3cfuns.com/tools.php?mod=regex

  正则表达式结构分析工具:https://regexper.com/#%2F%5E%5B1-9%5D%5Cd*%24%2F

  在正则表达式调试工具中,我们能调试我们想要的结果,在旁边还附有帮助文档,能帮助我们很好的使用;而结构分析工具能帮助我们更好的分析其中的结构。以电话号码的匹配为例

在调试工具中我们查看常用规则,点击手机,得到如下效果:在解析工具中我们可以根据结果分析它的结构,效果如图:刚开始学习的时候可以多借助工具,夺取分析结构,比较几个常用正则表达式的区别,然后进行归纳。

补充:RegExp实例继承的toLocaleString()和toString()方法都会返回正则表达式的面向字面量,与创建的表达式无关。

var reg = new RegExp("\\[bc\\]at","g");
console.log(reg.toLocaleString());
console.log(reg.toString()); var reg = /\[bc\]at/g;
console.log(reg.toLocaleString());
console.log(reg.toString())

输出的结果都为:/\[bc\]at/g

----------------------------------------10月9日更新----------------------

今天看到一个关于Javascript正则表达式的题目,在这里分享下:

题目:用javascript编写一个将十六进制值转换为颜色的函数 ,以蓝色为例,#0000FF 应该表示成“rgb(0,0,255)”的形式。

代码如下:

    function getRGB(hex){
var rgb=[,,];
if(/#(..)(..)(..)/g.test(hex)){
rgb=[parseInt(RegExp.$,),parseInt(RegExp.$,),parseInt(RegExp.$,)];
};
return "rgb("+rgb.join(",")+")";
}
var a = getRGB("#00ff00");
console.log(a);

----------------------------------------------10月15日更新------------------

对于用户名的要求:这里就直接码代码了

        <h3>要求:</h3>
<p>、只能输入5-20个字符,必须以字母开头</p>
<p>、可以带数字、下划线、点的字符串</p>
<hr />
<form action="#">
<label for="#">
用户名:<input type="text" id="name" class="text" />
</label>
<input type="button" id="submitBtn" class="btn" value="验证" />
</form> <script type="text/javascript">
window.onload = function(){
var oBtn = document.getElementById('submitBtn');
var oInput = document.getElementById("name");
oBtn.onclick = function(){
var reg = /^[a-z|A-Z]{}[/w|_.]{,}/g;
if(reg.test(oInput.value)==false){
alert("格式错误!");
}else{
alert("格式正确!");
}
}
}
</script>

Javascript中的正则表达式的更多相关文章

  1. JavaScript中的正则表达式(终结篇)

    JavaScript中的正则表达式(终结篇) 在之前的几篇文章中,我们了解了正则表达式的基本语法,但那些语法不是针对于某一个特定语言的.这篇博文我们将通过下面几个部分来了解正则表达式在JavaScri ...

  2. 浅谈JavaScript中的正则表达式

    引言 对于正则表达式我想作为程序员肯定使用过它,那天书般的表达方式,我用一次就记住它了.这篇博客先介绍一些正则表达式的内容,然后介绍JavaScript中对正则表达式特有的改进.下面开始介绍正则表达式 ...

  3. 转载 javascript中的正则表达式总结 一

    定义正则表达式的方法 定义正则表达式的方法有两种:构造函数定义和正则表达式直接量定义.例如: var reg1 = new RegExp('\d{5, 11}'); // 通过构造函数定义 var r ...

  4. C++、Java、JavaScript中的正则表达式

    C++(VS2013编译器):http://msdn.microsoft.com/zh-cn/library/bb982727.aspx#grammarsummary Java:            ...

  5. 浅谈JavaScript中的正则表达式(适用初学者观看)

    浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...

  6. 精通 JavaScript中的正则表达式

    精通 JS正则表达式 (精通?标题党 ) 正则表达式可以: •测试字符串的某个模式.例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式.这称为数据有效性验证  ...

  7. JavaScript中的正则表达式详解

    摘要:javascript中的正则表达式作为相当重要的知识,本文将介绍正则表达式的相关知识和用法. 正则表达式(Regular Expression)是一门简单语言的语法规范,是强大.便捷.高效的文本 ...

  8. javascript中的正则表达式学习

    一.前言 关于正则表达式自身的语法这里不做过多介绍(详情可参见http://www.php100.com/manual/unze.html),这里仅仅解释javascript中和正则表达式相关的几个方 ...

  9. JavaScript 中的正则表达式

    1.正则表达式概述 ECMAScript 3 开始支持正则表达式,其语法和 Perl 语法很类似,一个完整的正则表达式结构如下: 1 var expression = / pattern / flag ...

随机推荐

  1. [ASE]项目介绍及项目跟进——TANK BATTLE·INFINITE

    童年的记忆,大概是每周末和小伙伴们围坐在电视机前,在20来寸的电视机屏幕里守卫着这个至今都不知道是什么的白色大鸟. 当年被打爆的坦克数量估计也能绕地球个三两圈了吧. 十几年过去了,游戏从2D-3D,画 ...

  2. ASP.NET 4.5.256 has not been registered on the Web server. You need to manually configure your Web server for ASP.NET 4.5.256 in order for your site to run correctly

    Microsoft .NET Framework 4.6安装后,用户可能会在使用Microsoft Visual Studio 创建(或打开现有项目时)网站.或Windows Azure项目时遇到下面 ...

  3. CSS3之绽放的花朵(网页效果--每日一更)

    今天,带来的是纯CSS3打造的效果--绽放的花朵. 先来看效果吧:亲,请点击这里 这是纯CSS3样式打造的效果,关键是采用了animation属性和transform属性.详细请看下面代码. HTML ...

  4. 让人一用钟情的VS插件系列之一——Web Essentials(Web开发必备利器)

    返回VS插件总目录 本篇目录 初识Web Essentials 看国外大牛如何评价Web Essentials Web Essentials下载与安装 Web Essentials涉及到了哪些内容 初 ...

  5. mac 命令行批量删除.svn[转]

    mac下.svn是隐藏文件,而且即使我们调成可见的,一个一个删也很麻烦.今天正好同事问起来这个命令,于是想可能有些人也需要,于是还是放到博客里吧 命令比较简单,其实就是一条linux命令,打开终端,首 ...

  6. Linux下安装SVN服务端小白教程

    安装 使用yum安装非常简单: yum install subversion 配置 创建仓库 我们这里在/home下建立一个名为svn的仓库(repository),以后所有代码都放在这个下面,创建成 ...

  7. jQuery.fn.extend(object) object中this的指向

    看到下面的代码后,一下子懵逼了.这个this指向哪儿去了. jQuery.fn.extend({ check: function() { return this.each(function() { t ...

  8. 老学员的学习感悟 --prince2认证有什么用

    2007年一月,我加入了荷兰Irdeto(中国)有限公司.刚入公司,我就结识了PRINCE2(受控环境下的项目管理),才知道prince2是英国政府在政府项目中使用的项目管理标准.这一标准早已在欧洲广 ...

  9. Bootstrap~大叔封装的弹层

    回到目录 对于Bootstrap的弹层,插件有很多,今天主要用的是它自带的功能,通过bootstrap提供的模式窗口来实现的,而大叔主要对使用方法进行了封装,开发人员可以自己动态传入弹层的HTML内容 ...

  10. struts2学习笔记之十:文件上传

    Struts2的上传 1.Struts2默认采用了apache commons-fileupload 2.Struts2支持三种类型的上传组件 3.需要引入commons-fileupload相关依赖 ...