Js与正则表达式

h2 { text-align: left; box-shadow: 10px 10px 5px rgba(136, 136, 136, 1); backgr

  

  原本接着上面的章节,这一章节应该是写 Jquery事件的,由工作需要,暂时横插一篇正则表达式的学习,这里是边学边记录,错误之处,希望指正,提拔一二,不甚感激!

 

此章节有 

 

1.1 正则表达式的定义

1.2 Js中正则表达式的使用

  1.2.1 RegExp 对象

  1.2.2 String 对象

1.3 正则表达式

1.4 参考

 

1.1 正则表达式,什么是正则表达式?

  

  假如现在有一长段的字符串,检索某个或者某段文本时,需要某种规则来匹配某段或者某文本的时候,那么这种匹配规则我们就叫它正则表达式。正则表达式其实就是用于描述这些规则的代码。

 

1.2 Js中正则表达式的使用

 

  在js中,能够使用正则表达是的对象有 RegExp 对象 和 String 对象, 方法有test()、exec() 以及 compile(),这是RegExp对象的函数。还有String对象的,search()、match()、replace()、split()

 

1.2.1 RegExp 对象

  

  在javascript中,我们通过RegExp对象来存储正则表达式。RegExp 对象有 3 个方法:test()、exec() 以及 compile()。

  

  test() 方法检索字符串中的指定值。返回值truefalse

var patt1=new RegExp("e"); 
var TestString = "The best things in life are free"; 
alert(patt1.test(TestString)); //true

  上面的例子判断变量 TestString字符串中是否存在字母 "e",存在,所以弹出的是 true。

 

  exec() 方法检索字符串中的指定值。返回值是被找到的值(string)。如果没有发现匹配,则返回 null

var patt1 = new RegExp("free"); 
var TestString = "The best things in life are free"; 
alert(patt1.exec(TestString));//free

  字符串TestString中存在单词 "free",所以代码弹窗弹出的是:free 。

  在这里需要说明一下,RegExp 对象参数个数可以不止1个,两个参数也是可以的。

var patt1=new RegExp("e","?"); 

  第一个都已经知道了,匹配的表达式,那么第二个是什么呢?第二个,是指定的范围

  有"i","g","m"

  i(ignoreCase) : 执行对大小写不敏感的匹配。

  g(global) : 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。

  m(multiline) : 执行多行匹配。

var str = "Is this all there is?"; 
var patt1 = new RegExp("is", "gi");
do 
{
     alert(patt1.exec(str)); 
} while (patt1.exec(str) != null)

  这里将弹出的是 Is is,在使用 "gi" 参数时,忽略大小写,找到第一个 "is",并存储其位置,如果再次运行 exec(),则从存储的位置开始检索,并找到下一个 "e",并存储其位置......

 

  compile() 方法用于改变 RegExp对象,既可以改变检索的正则表达式,也可以添加或删除第二个参数。

var str = "Is this all there is?"; 
var patt1 = new RegExp("is", "gi"); 
do 
{
     document.write("1: " + patt1.exec(str) + "  "); //1: Is  1: is
}
while (patt1.exec(str) != null) /*去掉不区分大小写*/ patt1.compile("is", "g") //document.write("2: " + patt1.exec(str)); do { document.write("2: " + patt1.exec(str) + " "); // 2: is  2: null  2: is
}
while (patt1.exec(str) != null) /*去掉第二个参数*/ patt1.compile("all", "g") document.write("3: " + patt1.exec(str));//3: all

 

1.2.2 String 对象

 

  在js中,能使用正则表达式的,不仅仅有RegExp对象,还有String对象的个别方法也能使用正则表达式。

  这些方法有:

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

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

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

  split : 把字符串分割为字符串数组。 下面我们分别来看一下各个函数的使用方法

 

  search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。返回值是所检索匹配到的字符串下标位置 (0 开始)。如果没有找到返回的是-1

  语法:

stringObject.search(string/regexp) 

  参数regexp,可以是需要在 stringObject 中检索的子串,也可以是需要检索的 RegExp 对象。search()方法不执行全局匹配,他忽略标志“g”, 它同时忽略 regexp 的 lastIndex 属性,并且总是从字符串的开始进行检索,这意味着它总是返回 stringObject 的第一个匹配的位置。

var str = "Hello World!";
document.write(str.search("hello")); //-1 
document.write(str.search("hello", "i")); //0 支持i 忽略大小写 
document.write(str.search(/Hello/)); //0 document.write(str.search(/world/)); //-1 
document.write(str.search(/World/i)); //6 不支持g,但支持i 忽略大小写

 

  match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。该方法类似 indexOf() 和 lastIndexOf(),但是它返回指定的值(string),而不是字符串的位置。

stringObject.match(string/regexp)

  match() 方法将检索字符串 stringObject,以找到一个或多个与 regexp 匹配的文本,以数组的方式返回。

   如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配

    如果没有找到任何匹配的文本, match() 将返回 null

    否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。

      该数组的第0个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。

      除了这些常规的数组元素之外,返回的数组还含有两个对象属性。index 属性声明的是匹配文本的起始字符在 stringObject 中的位置,input 属性声明的是对 stringObject 的引用。

  如果 regexp 具有标志 g,则 match() 方法将执行全局检索,找到 stringObject 中的所有匹配子字符串。

    若没有找到任何匹配的子串,则返回null

      如果找到了一个或多个匹配子串,则返回一个数组。

        不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中存放的是 stringObject 中所有的匹配子串,而且也没有 index 属性或 input 属性。

 

  注意:在全局检索模式下,match() 即不提供与子表达式匹配的文本的信息,也不声明每个匹配子串的位置。如果您需要这些全局检索的信息,可以使用 RegExp.exec()。

/*字符串匹配*/ 
var str = "Hello world!Hello world!Hello world!"; 
var pattworld = new RegExp("world"); 
var pattWorldi = new RegExp("World", "i"); 
var pattworlld = new RegExp("worlld"); 
var pattworldg = new RegExp("world!", "g"); 
document.write(str.match(pattworld) + "<br />"); //匹配字符串 返回world 
document.write(str.match(pattWorldi) + "<br />"); //匹配字符串 忽略大小写 返回world 
document.write(str.match(pattworlld) + "<br />"); //匹配字符串 未找到 返回null 
document.write(str.match(pattworldg)); //多次匹配,返回字符串数组


/*数字匹配 取字符串中的所有数字*/ 
var str = "7asdg8ga9fads99as0dfg8sdg9"; 
document.write(str.match(new RegExp(/\d/)));//匹配一次 7 
document.write(str.match(new RegExp(/\d+/g))); //全局匹配 7,8,9,99,0,8,9 应返回的是数据,输出都有','隔开

 

  replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。返回一个替换过,新的字符串(string)。 

stringObject.replace(regexp/substr,replacement)

  regexp/substr :字符串或者正则表达式

  replacement :可以是字符串也可以是函数 

  replace() 方法执行的是查找并替换的操作。

    它将在 stringObject 中查找与 regexp 相匹配的子字符串,然后用 replacement 来替换这些子串。

      如果 regexp 具有全局标志 g,那么 replace() 方法将替换所有匹配的子串。否则,它只替换第一个匹配子串。

/*1.文本替换*/ 
var str = "Hello The World!Hello the World!Hello The World!Hello The World!Hello the World!"; 
document.write(str); //Hello The World!.... 
document.write("<br/>"); // 
document.write(str.replace(/The World/gi, " ")); //Hello !....参数/The World/? 问号后可替换成g/i 

/*2.单词顺序调换*/ name = "Doe, John"; 
document.write(name.replace(/(\w+)\s*, \s*(\w+)/, "$2 $1")); //John Doe 

 

  说明:

    \w 匹配字母或数字或下划线或汉字(匹配字符串)。

    x+ 匹配重复1次或更多次(次数)。

    \s 匹配任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格等(匹配后得到的是空格)。

    x* 匹配任何包含零个或多个 x 的字符串(匹配后得到的是数量)。

 

  split() 方法用于把一个字符串分割成字符串数组。返回一个字符串数组返回的函数中并不包括第一个参数的字符串,或者正则表达式匹配的字符串。

stringObject.split(string/regexp,howmany)

  第一个参数 : 字符串或正则表达式,从该参数指定的地方分割 stringObject。

  第二个参数 : 可选。该参数可指定返回的数组的最大长度。

  如果设置了该参数,返回的子串不会多于这个参数指定的数组。     

  如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。     

 

  注释:   如果把空字符串 ("") 用作 第一个分割参数的话,那么 stringObject 中的每个字符之间都会被分割。   

      String.split() 执行的操作与 Array.join 执行的操作是相反的。    

var str = "What do you want to do today ?"; 
document.write(str.split(" ") + "<br />"); //What,do,you,want,to,do,today,? 
document.write(str.split("") + "<br />"); //W,h,a,t, ,d,o, ,y,o,u, ,w,a,n,t, ,t,o, ,d,o, ,t,o,d,a,y, ,? 
document.write(str.split(" ", 3)); //What,do,you

var str = "What do you want to do today ?"; 
document.write(str.split(/\s/) + "<br />"); //What,do,you,want,to,do,today,?

 

1.3 正则表达式

 

  在线测试正则表达式我用,这个

  入门

  有的时候我们会查找指定的字符,比如我们用 is 查句子"Is this all there is?" 是否存在, 利用上面的在线测试会查到两个被选择 this 和 is ,

  如果忽略了大小写的话 Is 也是会出来的,这时候,我们可以用 \b 了,正则表达式可写成 \bis\b。这样匹配的就只有 is 了(不忽略大小写的时候)。

  

  \b 是一个元字符(元字符是一个或一组代替一个或多个字符的字符),它匹配单词边界。

    如果你要查找一段指定的字符串比如 this … is. 只在乎开头是this,结尾是is的时候,正则表达式就应该这样写了 \bthis\b.*\bis\b精确匹配。

  .  元字符,匹配除了换行符以外的任意字符 ,

  * 元字符,代表这数量,表示 * 前面出现的内容可以连续出现任意个(零个或多个)。\bthis\b.*\bis\b所以这个就好解释了,匹配有this 有is 的字符串,中间不管有什么(不能有换行)的字符串。

  \d 匹配数字 ,0\d 匹配0开头的两位数字 “0465061”能匹配到04 06 ,0\d\d\d 匹配四位数字 0465 也可写成 0\d{3}

  \w 匹配字母,\ba\w*\b 匹配以字母a开头的单词 able 。\b\w{6}\b 匹配刚好6个字符的单词。

  + 匹配1个或更多与*的区别是至少有一个,\d+ 匹配1个或更多连续的数字。

  ^ 匹配正则表达式以什么开头,一个位置

  $ 匹配正则表达式以什么结尾,一个位置 , 如:^n.*m$ 匹配n开头m结尾不管中间有什么(换行除外)的字符串。

  {5,12} 重复的次数不能少于5次,不能多于12次 ^\d{5,12}$ 匹配5-12位开头结尾都是数字的字符串,可用于QQ号匹配。(^$可定义范围 i,g,m)

  \ 转义字符,当匹配的字符串中有 .*这样的字符的时候,为了不让.*起作用,我们需要把它转义,就当一个字符来用

        如:用 cnblogs\.com\/\w* 匹配 cnblogs.com/Jolinson 的时候

   Table_正则

元字符说明 量数限定说明
. 匹配除换行符以外的任意字符   * 重复零次或更多次
\w 匹配字母或数字或下划线或汉字   + 重复一次或更多次
\s 匹配任意的空白符   ? 重复零次或一次
\d 匹配数字   {n} 重复n次
\b 匹配单词的开始或结束   {n,} 重复n次或更多次
^ 匹配字符串的开始   {n,m} 重复n到m次
$ 匹配字符串的结束      

  更多元字符匹配请点击这里

  []  自定义集合,比例 [is] 匹配 Is this all there is? 出现三个i或者s。

  [0-9] 代表的含意与\d就是完全一致的:一位数字;同理[a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)。

  [.?!·,。] 匹配标点符号(.或?或!)。 

  看看这个 \(?0\d{2}[)-]?\d{8}

  首先是一个转义字符加左小括号 \( 他出现(0次)或者不出现(1次),然后是个0在后面跟着连个数字,数字后面有[) -]出现或者不出现,最后是八位连续的数字,

  那么它可以匹配的是:01288888888,(020)55555555,010-66666666,(020-77777777

  反义:元字符范围取反

代码说明
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符

    

  如:

    \S+匹配不包含空白符的字符串。

    <a[^>]+>匹配用尖括号括起来的以a开头的字符串。

 

 升级

  分枝条件:

    正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用 | 把不同的规则分隔开。

    如:

    0\d{2}-\d{8}|0\d{3}-\d{7}

    这个表达式 能匹配 0开头连着两位数再 - 然后八位数的号码010-12345678,也能匹配0开头连着三位数再 - 然后七位数的号码 0123-1234567

    \(?0\d{2}\)?[- ]?\d{8}|0\d{2}[- ]?\d{8}

    这个表达式能匹配 可以有,可以没有;0开头后面跟着两个)可以有可以没有;-空格 可以有其中一个可以都没有;后面八位数;

    或:0开头后面跟着两位数;-空格 可以有其中一个可以都没有;后面八位数;

    可以匹配的数字:(012-01234567 012-01234567  012)-01234567  01201234567 (012)-01234567 (012) 01234567

    有单边括号,不好,不好!改改!

    \(0\d{2}\)[- ]\d{8}|0\d{2}[- ]\d{8}|0\d{3}[- ]\d{7}|\(0\d{3}\)[- ]\d{7}

    匹配的就干净多了!

    012-12345678 012-12345678 (012)-12345678 (012) 12345678 0797 1234567 0797-1234567 (0797)-1234567

    分支条件注意的地方:

      1.\d{2}|\d{3} 和 2.\d{3}|\d{2} 这两个正则

      \d{2}|\d{3} 使用这个正则的时候,只会匹配2个数2个数,永远不会匹配到三个数,因为\d{3}成立的同时,肯定\d{2}也成立,只执行其一,从左往右。所以全部都是 12 12 12 12 模式

      \d{3}|\d{2} 就不一样了,匹配 \d{3}的同时,还会匹配 \d{2} 的正则。

      如:12345678 如果使用1.\d{2}|\d{3}会得到12345678 使用2.\d{3}|\d{2}会得到12345678  

      原来的例子是:

      \d{5}-\d{4}|\d{5} 与 \d{5}|\d{5}-\d{4}

      \d{5}-\d{4}|\d{5}这个表达式用于匹配美国的邮政编码。美国邮编的规则是5位数字,或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题:

      使用分枝条件时,要注意各个条件的顺序。如果你把它改成\d{5}|\d{5}-\d{4}的话,那么就只会匹配5位的邮编(以及9位邮编的前5位)。

      原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。(与 || 逻辑运算)

 

  分组:

    通过上面所了解到的,

    * 重复零次或者更多

    + 重复一次或者更多

    ?重复零次或者一次

    {n}重复n次

    {n,}重复n次,或超过n次

    {n,m}重复n到m次。

    我们可以利用上面的进行分组,组合子表达式用()括起!

    如:

    n{3} 匹配3个连续的n

    (nm){3} 匹配3个连续的 nm

    利用小括号来指定子表达式叫做分组

    又如

    (\d{1,3}\.){3}\d{1,3}

    它能匹配

    1.1.1.1 到 999.999.999.999 的数字,有点想Ip可是完全超标了。

    解说:(\d{1,3}\.){3}小括号中 1位或2位或3位数字加个. 重复3次\d{1,3}1位或2位或3位数字

    试用分组写个Ip表达式子,IP地址中每个数字都不能大于255。 01.02.03.04 一是一种正确的IP。

    

试写的路

(0?\d\.|0?\d{2}\.|[012][0-5]{2}\.){3}0?\d|0?\d{2}|[012][0-5]{2}

惨不忍睹 x 1

([012][0-5]{2}\.|0?\d{2}\.|0?\d\.){3}[012][0-5]{2}|0?\d{2}|0?\d

惨不忍睹 x 2

.....

惨不忍睹 x n

((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)

√ 老师傅的正则

([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}

X 网上随便找了一个一坨屎

(([01]\d{2}\.|\d{2}\.|\d\.)){3}([01]\d{2}|\d{2}|\d)

√ 有效果 +1

((2[0-5]{2}\.|[01]\d{2}\.|\d{2}\.|\d\.)){3}(2[0-5]{2}|[01]\d{2}|\d{2}|\d)

√ 有效果 +2 修改版

(2[0-5]\d\.|1\d{2}\.|\d{2}\.|\d\.){3}(2[0-5]\d|1\d{2}|\d{2}|\d)

√ ok最终版

99.999.999.999  1.1.1.1 01.01.01.01 01.02.03.04 255.255.255.255 192.168.1.1

999.999.999.999 99.99.99.99 114.168.1.1 200.30.11.01 115.239.210.27 159.18.18.1 26.2.48.54 46.568.218.546

 

又写了一个 日期的

[012]\d{3}[- /]?([01]?\d|\d)[- /]?(\d{2}|0\d|\d)

2013-01-01 1989-9-9 0001-01-01 1991-02-25 20131217 2013/12/14  20131214

这东西,要复杂能写很负责,要简单,可以定的死死的

(来我这浏览的观客们,千万不要拿我试手的正则去用,因为我没认真仔细反反覆覆的测过,出了错我不负责的。。。上面的那个日期就得优化,因为他能匹配很多怪胎…

2013-2-33 20080888 00121236 2878-6-54 以后可以回来试试,难道每个数字写好规则才是最严谨的匹配?)

 

  以下完全属于摘抄:

  组号:1.默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号(为标志,第一个出现的分组的组号为1,第二个为2,以此类推。

  2.组名也可以自己定义:语法 (?<Word>\w+) 或者 (?'Word'\w+)

  3.(?:exp)不会改变正则表达式的处理方式,只是这样的组匹配的内容不会像前两种那样被捕获到某个组里面,也不会拥有组号。

 

  后向引用:用于重复搜索前面某个分组匹配的文本。

  \b(\w+)\b\s+\1\b 如这个可用来匹配重复的单词 hello hello go go  1 = (\w+)的值

  一定的程度上可以理解成\b(\w+)\b\s+\1\b = \b(\w+)\b\s+\b(\w+)\b , 可是 \b(\w+)\b\s+\1\b 的1,是\b(\w+)\b匹配的内容的重复。

 

  (?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。

  如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找going时,它会匹配go.

 

  (?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。

  如(?<=\bgo)\w+\b会匹配以go开头的单词的后半部分(除了go以外的部分),例如在查找going时,它匹配ing。

  更多可浏览前人指路链接:

  注释:

  贪婪与懒惰:

  处理选项:

  平衡组/递归匹配:

 

参考

前人指路 : 正则表达式30分钟入门教程

您可能有感兴趣的文章
Webpack优化配置缩小文件搜索范围

JavaScript代码性能优化总结(推荐)

JS正则表达式完整好代码教程

常用JavaScript正则表达式整理

JavaScript:正则表达式(入门篇)