js——正则匹配

1、示例

匹配网址url

function IsURL(str_url){
    var strRegex = "^((https|http|ftp|rtsp|mms)?://)"
          + "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" //ftp的user@ 
          + "(([0-9]{1,3}\.){3}[0-9]{1,3}" // IP形式的URL- 199.194.52.184 
          + "|" // 允许IP和DOMAIN(域名)
          + "([0-9a-z_!~*'()-]+\.)*" // 域名- www. 
          + "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\." // 二级域名 
          + "[a-z]{2,6})" // first level domain- .com or .museum 
          + "(:[0-9]{1,4})?" // 端口- :80 
          + "((/?)|" // a slash isn't required if there is no file name 
          + "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$"; 
    var re=new RegExp(strRegex); 
    if (re.test(str_url)){
        return (true); 
    }else{ 
        return (false); 
    }
}
var testUrl;
testUrl="harveyzeng.iteye.com/blog/1776991";
alert(IsURL(testUrl));

匹配手机号码

var mobile = /^(13[0-9]{9})|(18[0-9]{9})|(14[0-9]{9})|(17[0-9]{9})|(15[0-9]{9})$/;
// 或
var mobile = /^1[34578]\d{9}$/;

匹配固话

var tel = /^([0-9]{3,4}-)?[0-9]{7,8}$/;

匹配身份证号码

var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;

匹配密码

// 以字母开头,长度在6-18之间,只能包含字符、数字和下划线
var password = /^[a-zA-Z]\w{5,17}$/;

匹配一年的12个月

var month = /^(0?[1-9]|1[0-2])$/;

匹配一个月的31天

var day = /^((0?[1-9])|((1|2)[0-9])|30|31)$/;

匹配Email地址

var email = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/;

匹配汉字

var n = /^[\u4e00-\u9fa5],{0,}$/;

匹配html标签

var html = /<(.*)>(.*)<\/(.*)>|<(.*)\/>/;

用正则表达式限制只能输入中文

onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,''))"

用正则表达式限制只能输入数字和英文

onkeyup="value=value.replace(/[\W]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"

2、 可选项修饰符,可以组合使用

  • g : 全文查找
  • i :忽略大小写
  • m : 多行查找

3、正则表达式模式

表达式 描述
[abc] 匹配 abc 其中的一个
[^abc] 匹配 除abc 之外的字符
(x|y) 匹配 x 或者 y

4、正则表达式中的预定义类

代码 等同于 匹配
. IE下[^\n],其他[^\n\r] 匹配除了换行和行结束符之外的单个字符
\d [0-9] 匹配数字
\D [^0-9] 匹配非数字字符
\b /\bc/.exec('acbc');匹配右侧边界的c 匹配单词边界
\B /\Bc/.exec('bcbc') ;成功地匹配到bcbc中的c 匹配非单词边界
\s [\n\r\t\f\x0B] 匹配一个空白字符
\S [^\n\r\t\f\x0B] 匹配一个非空白字符
\w [a-zA-Z0-9_] 匹配字母数字和下划线
\W [^a-zA-Z0-9_] 匹配除字母数字下划线之外的字符
\0 查找NULL字符
\n 查找换行符
\xxx 查找以八进制数 xxx 规定的字符
\xdd 查找以十六进制数 dd 规定的字符
\uxxxx 查找以十六进制数 xxxx 规定的 Unicode 字符

5、量词(下表量词到{n,m}之前,单个出现时皆是贪婪量词)

代码 描述 示例
* 匹配零次或多次 zo* 能匹配 “z” 以及 “zoo” 。等价于 {0,}
+ 匹配一次或多次 'zo+' 能匹配 “zo” 以及 “zoo” ,但不能匹配 “z” 。等价于 {1,}
匹配零次或一次 "do(es)?" 可以匹配 "do" 或 "does" 中的 "do" 。? 等价于 {0,1}
{n} n 是一个非负整数。匹配确定的 n 次 'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o
{n,} n 是一个非负整数,至少匹配 n 次 'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。 'o{1,}' 等价于 'o+' 。 'o{0,}' 则等价于 'o*'
{n,m} m 和 n 均为非负整数,其中n<=m。最少匹配n次且最多匹配m次 "o{1,3}" 将匹配 "fooooood" 中的前三个 o。 'o{0,1}' 等价于 'o?' 。请注意在逗号和两个数之间不能有空格
n$ 匹配以n结尾的字符串
^n 匹配以n开头的字符串
?=n 匹配任何其后紧接指定字符串n的字符串 (?=pattern)所谓正向预查,意思就是:要匹配的字符串,后面必须紧跟着pattern。我们知道正则表达式/cainiao/会匹配cainiao。同样,也会匹配cainiao9中的cainiao。但是我们可能希望,cainiao只能匹配cainiao8中的cainiao。这时候就可以像下面这样写:/cainiao(?=8)/
?!n 匹配任何其后没有紧接指定字符串n的字符串

6、 贪婪量词与惰性量词

贪婪量词进行匹配时,它首先会将整个字符串当成一个匹配,如果匹配的话就退出。如果不匹配,就把最后一个字符去掉再进行匹配,不匹配继续去掉最后一个字符,直到找到一个匹配或者不剩任何字符为止

惰性量词进行匹配时,先看第一个字符串是否匹配,如果不匹配就加入第二个字符串以此类推,直到找到一个匹配或者不剩任何字符为止

// 惰性量词仅仅在贪婪量词后面加个"?"而已,如"a+"是贪婪匹配的,"a+?"则是惰性的 
var str = "abc";
var re = /\w+/; // 将匹配abc
re = /\w+?/; // 将匹配a

7、分组与非捕获性分组

    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  

8、反向引用

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

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这类方法中可用特殊字符序列来表示反向引用 
re = /(\d)\s(\d)/;  
str = "1234 5678";  
alert(str.replace(re,"21"));//在这个里面1表示第一个分组1234,2则表示5678  

9、正向前瞻

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

    //正向前瞻  
    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  

10、正则表达式对象的方法

match: 使用正则表达式模式对字符串执行查找,并将包含查找的结果作为数组返回

stringObj.match(rgExp)
// 如果match的表达式匹配了全局标记g将出现所有匹配项,而不用循环,但所有匹配中不会包含子匹配项

exec: 用正则表达式模式在字符串中运行查找,并返回包含该查找结果的第一个值(数组),如果匹配失败,返回null
test: 返回一个Boolean值,它指出在被查找的字符串中是否匹配给出的正则表达式。
search: 返回与正则表达式查找内容匹配的第一个子字符串的位置(偏移位),如果没有返回-1
replace: 返回根据正则表达式进行文字替换后的字符串的复制

// 语法:
stringObj.replace(rgExp, replaceText)
// 示例
function f2c(s) {
    var test = /([\d]{4})-([\d]{1,2})-([\d]{1,2})/;
    return(s.replace(test,  function($0,$1,$2,$3) {
        return($2 +"/" + $1);
    }));
}
document.write(f2c("today: 2011-03-29")); 
// 输出:today: 03/2011

split: 将一个字符串分割为子字符串,然后将结果作为字符串数组返回
compile: 用于在脚本执行过程中编译正则表达式;也可用于改变和重新编译正则表达式

// 语法
stringObj.compile(rgExp,可选项修饰符(见2))
// 示例
var str="Every man in the world! Every woman on earth!";

patt=/man/g;
str2=str.replace(patt,"person");
document.write(str2+"<br />");

patt=/(wo)?man/g;
patt.compile(patt);
str2=str.replace(patt,"person");
document.write(str2);

/* 输出:
Every person in the world! Every woperson on earth!
Every person in the world! Every person on earth!
*/

11、 正则表达式对象的属性

source: 返回正则表达式模式的文本的复本,只读

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

lastindex: 返回字符位置,它是被查找字符串中下一次成功匹配的开始位置,默认值是-1

    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  

1-9: 返回九个在模式匹配期间找到的、最近保存的部分。只读。
input($_):返回执行规范表述查找的字符串。只读

//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($&): 返回任何正则表达式搜索过程的最后匹配的字符。只读

//lastMatch 最后匹配的字符  
re = /[a-z]/g;  
str = "hi";  
re.test(str);  
alert(RegExp.lastMatch);//h  
re.test(str);  
alert(RegExp["$&"]);//i  ,$&是lastMatch的短名字,但它不是合法变量名  

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

//lastParen 最后匹配的分组  
re = /[a-z](\d+)/gi;  
str = "Class1 Class2 Class3";  
re.test(str);  
alert(RegExp.lastParen);//1  
re.test(str);  
alert(RegExp["$+"]);//2  

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

//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不支持这个属性,所以最好还是单独指定
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

参考:
http://www.cnblogs.com/zfc2201/archive/2012/12/18/2824107.html
http://www.jb51.net/article/28007.htm
http://www.cnblogs.com/aaronjs/archive/2012/06/30/2570970.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容