精华内容
下载资源
问答
  • 正则表达式 1. 什么是正则表达式? 百度百科提供的概念是这样的:正则表达式,又称规则表达式**。**(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。其通常被用来检索、...

    正则表达式

    1. 什么是正则表达式?

    百度百科提供的概念是这样的:正则表达式,又称规则表达式**。**(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。其通常被用来检索、替换那些符合某个模式(规则)的文本

    正则表达式其实是对字符串操作的一种公式,通过组合一些具有特殊含义的字符,来实现用户的操作逻辑,从而对文本完成操作。我们一般称这些“特殊字符的组合”为规则字符串

    在不同语言中,正则表达式有不同的变种,具体情况我们会在后文以JavaScriptPython为例进行说明

    2. 元字符

    正则表达式由一些普通字符和一些元字符(metacharacters)组成

    普通字符包括大小写的字母和数字,而元字符则具有特殊的含义,相关含义如下表所示:

    元字符含义
    \转义字符。例如,“n”会匹配小写字母n,但是“\n”则会匹配换行符\n
    ^匹配行首
    $匹配行尾
    ***匹配前面的子表达式任意次(大于等于0次)。**例如,zo*能匹配“z”,也能匹配“zo”以及“zoo”。*等价于{0,}。
    +**匹配前面的子表达式一次或多次(大于等于1次)。**例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
    ?**匹配前面的子表达式0次或1次。**例如,“do(es)?”可以匹配“do”或“does”。?等价于{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}**表示最少匹配n次且最多匹配m次,其中mn均为非负整数,其中n<=m。**例如,“o{1,3}”将匹配“fooooood”中的前三个o为一组,后三个o为一组。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
    ?当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少地匹配所搜索的字符串,而默认的贪婪模式则尽可能多地匹配所搜索的字符串。例如,对于字符串“oooo”,“o+”将尽可能多地匹配“o”,得到结果[“oooo”],而“o+?”将尽可能少地匹配“o”,得到结果 [‘o’, ‘o’, ‘o’, ‘o’]
    .**匹配除“\n”和"\r"之外的任何单个字符。**要匹配包括“\n”和"\r"在内的任何字符,请使用像“[\s\S]”的模式。
    x|y**匹配x或y。**例如,“z|food”能匹配“z”或“food”。“[z|f]ood”则匹配“zood”或“food”。
    [xyz]**字符集合。**匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。
    [^xyz]**负值字符集合。**匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“plin”任一字符。
    [a-z]**字符范围。**匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。注意:只有连字符在字符组内部时,并且出现在两个字符之间时,才能表示字符的范围; 如果出字符组的开头,则只能表示连字符本身.
    [^a-z]**负值字符范围。**匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。
    \b匹配一个单词的边界,也就是指单词和空格间的位置(即正则表达式的“匹配”有两种概念,一种是匹配字符,一种是匹配位置,这里的\b就是匹配位置的)。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”;“\b1_”可以匹配“1_23”中的“1_”,但不能匹配“21_3”中的“1_”。
    \B匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。
    \cx**匹配由x指明的控制字符。**例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。
    \d**匹配一个数字字符。**等价于[0-9]。grep 要加上-P,perl正则支持
    \D**匹配一个非数字字符。**等价于[^0-9]。grep要加上-P,perl正则支持
    \f**匹配一个换页符。**等价于\x0c和\cL。
    \n**匹配一个换行符。**等价于\x0a和\cJ。
    \r**匹配一个回车符。**等价于\x0d和\cM。
    \s**匹配任何不可见字符,包括空格、制表符、换页符等等。**等价于[ \f\n\r\t\v]。
    \S**匹配任何可见字符。**等价于[^ \f\n\r\t\v]。
    \t**匹配一个制表符。**等价于\x09和\cI。
    \v**匹配一个垂直制表符。**等价于\x0b和\cK。
    \w**匹配包括下划线的任何单词字符。**类似但不等价于“[A-Za-z0-9_]”,这里的"单词"字符使用Unicode字符集。
    \W**匹配任何非单词字符。**等价于“[^A-Za-z0-9_]”。
    \xn**匹配n,其中n为十六进制转义值。**十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。
    *num***匹配num,其中num是一个正整数。对所获取的匹配的引用。**例如,“(.)\1”匹配两个连续的相同字符。
    *n***标识一个八进制转义值或一个向后引用。**如果*n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n*为一个八进制转义值。
    *nm***标识一个八进制转义值或一个向后引用。*如果*nm之前至少有nm个获得子表达式,则nm为向后引用。如果*nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若nm均为八进制数字(0-7),则*nm将匹配八进制转义值nm
    *nml*如果n为八进制数字(0-7),且ml均为八进制数字(0-7),则匹配八进制转义值nml
    \un**匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。**例如,\u00A9匹配版权符号(©)。
    \p{P}**小写 p 是 property 的意思,表示 Unicode 属性,用于 Unicode 正表达式的前缀。**中括号内的“P”表示Unicode 字符集七个字符属性之一:标点字符。其他六个属性:L:字母;M:标记符号(一般不会单独出现);Z:分隔符(比如空格、换行等);S:符号(比如数学符号、货币符号等);N:数字(比如阿拉伯数字、罗马数字等);C:其他字符。*注:此语法部分语言不支持,例:javascript。
    <>**匹配词(word)的开始(<)和结束(>)。**例如正则表达式<the>能够匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"。注意:这个元字符不是所有的软件都支持的。
    ( )将( 和 ) 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 \1 到\9 的符号来引用。
    |**将两个匹配条件进行逻辑“或”(or)运算。**例如正则表达式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:这个元字符不是所有的软件都支持的。

    在正则表达式中,如果直接给出字符,就是精确匹配。用\d可以匹配一个数字,\w可以匹配一个字母或数字,所以:

    • '00\d'可以匹配'007',但无法匹配'00A'
    • '\d\d\d'可以匹配'010'
    • '\w\w\d'可以匹配'py3'

    .可以匹配任意字符,所以:

    • 'py.'可以匹配'pyc''pyo''py!'等等。

    要匹配变长的字符,在正则表达式中,用*表示任意个字符(包括0个),用+表示至少一个字符,用?表示0个或1个字符,用{n}表示n个字符,用{n,m}表示n-m个字符:

    来看一个复杂的例子:\d{3}\s+\d{3,8}

    我们来从左到右解读一下:

    1. \d{3}表示匹配3个数字,例如'010'
    2. \s可以匹配一个空格(也包括Tab等空白符),所以\s+表示至少有一个空格,例如匹配' '' '等;
    3. \d{3,8}表示3-8个数字,例如'1234567'

    综合起来,上面的正则表达式可以匹配以任意个空格隔开的带区号的电话号码。

    如果要匹配'010-12345'这样的号码呢?由于'-'是特殊字符,在正则表达式中,要用'\'转义,所以,上面的正则是\d{3}\-\d{3,8}

    但是,仍然无法匹配'010 - 12345',因为带有空格。所以我们需要更复杂的匹配方式。

    要做更精确地匹配,可以用[]表示范围,比如:

    • [0-9a-zA-Z\_]可以匹配一个数字、字母或者下划线;
    • [0-9a-zA-Z\_]+可以匹配至少由一个数字、字母或者下划线组成的字符串,比如'a100''0_Z''Py3000'等等;
    • [a-zA-Z\_][0-9a-zA-Z\_]*可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是Python合法的变量;
    • [a-zA-Z\_][0-9a-zA-Z\_]{0, 19}更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。

    A|B可以匹配A或B,所以(P|p)ython可以匹配'Python'或者'python'

    ^表示行的开头,^\d表示必须以数字开头。

    $表示行的结束,\d$表示必须以数字结束。

    你可能注意到了,py也可以匹配'python',但是加上^py$就变成了整行匹配,就只能匹配'py'了。

    3. Python中的正则表达式

    3.1 re模块

    有了准备知识,我们就可以在Python中使用正则表达式了。Python提供re模块,包含所有正则表达式的功能。由于Python的字符串本身也用\转义,所以要特别注意:

    s = 'ABC\\-001' # Python的字符串
    # 对应的正则表达式字符串变成:
    # 'ABC\-001'
    

    因此我们强烈建议使用Python的r前缀,就不用考虑转义的问题了:

    s = r'ABC\-001' # Python的字符串
    # 对应的正则表达式字符串不变:
    # 'ABC\-001'
    

    先看看如何判断正则表达式是否匹配:

    >>> import re
    >>> re.match(r'^\d{3}\-\d{3,8}$', '010-12345')
    <_sre.SRE_Match object; span=(0, 9), match='010-12345'>
    >>> re.match(r'^\d{3}\-\d{3,8}$', '010 12345')
    >>>
    

    match()方法判断是否匹配,如果匹配成功,返回一个Match对象,否则返回None。常见的判断方法就是:

    test = '用户输入的字符串'
    if re.match(r'正则表达式', test):
        print('ok')
    else:
        print('failed')
    

    3.2 分组

    除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组(Group)。比如:

    ^(\d{3})-(\d{3,8})$分别定义了两个组,可以直接从匹配的字符串中提取出区号和本地号码:

    >>> m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
    >>> m
    <_sre.SRE_Match object; span=(0, 9), match='010-12345'>
    >>> m.group(0)
    '010-12345'
    >>> m.group(1)
    '010'
    >>> m.group(2)
    '12345'
    

    如果正则表达式中定义了组,就可以在Match对象上用group()方法提取出子串来

    注意到group(0)永远是原始字符串,group(1)group(2)……表示第1、2、……个子串

    提取子串非常有用。来看一个更凶残的例子:

    >>> t = '19:05:30'
    >>> m = re.match(r'^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$', t)
    >>> m.groups()
    ('19', '05', '30')
    

    这个正则表达式可以直接识别合法的时间。但是有些时候,用正则表达式也无法做到完全验证,比如识别日期:

    '^(0[1-9]|1[0-2]|[0-9])-(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[0-9])$'
    

    对于'2-30''4-31'这样的非法日期,用正则还是识别不了,或者说写出来非常困难,这时就需要程序配合识别了

    3.3 贪婪匹配

    最后需要特别指出的是,正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。举例如下,匹配出数字后面的0

    >>> re.match(r'^(\d+)(0*)$', '102300').groups()
    ('102300', '')
    

    由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串了

    必须让\d+采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0匹配出来,加个?就可以让\d+采用非贪婪匹配:

    >>> re.match(r'^(\d+?)(0*)$', '102300').groups()
    ('1023', '00')
    

    3.4 编译

    当我们在Python中使用正则表达式时,re模块内部会干两件事情:

    1. 编译正则表达式,如果正则表达式的字符串本身不合法,会报错
    2. 用编译后的正则表达式去匹配字符串

    如果一个正则表达式要重复使用几千次,出于效率的考虑,我们可以预编译该正则表达式,接下来重复使用时就不需要编译这个步骤了,直接匹配:

    >>> import re
    # 编译:
    >>> re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$')
    # 使用:
    >>> re_telephone.match('010-12345').groups()
    ('010', '12345')
    >>> re_telephone.match('010-8086').groups()
    ('010', '8086')
    

    编译后生成Regular Expression对象,由于该对象自己包含了正则表达式,所以调用对应的方法时不用给出正则字符串

    4. JavaScrip中的正则表达式

    4.1 描述字符

    根据正则表达式语法规则,大部分字符仅能够描述自身,这些字符被称为普通字符,如所有的字母、数字等。

    元字符就是拥有特动功能的特殊字符,大部分需要加反斜杠进行标识,以便于普通字符进行区别,而少数元字符,需要加反斜杠,以便转译为普通字符使用。JavaScript 正则表达式支持的元字符如表所示。

    元字符描述
    .查找单个字符,除了换行和行结束符
    \w查找单词字符
    \W查找非单词字符
    \d查找数字
    \D查找非数字字符
    \s查找空白字符
    \S查找非空白字符
    \b匹配单词边界
    \B匹配非单词边界
    \0查找 NUL字符
    \n查找换行符
    \f查找换页符
    \r查找回车符
    \t查找制表符
    \v查找垂直制表符
    \xxx查找以八进制数 xxxx 规定的字符
    \xdd查找以十六进制数 dd 规定的字符
    \uxxxx查找以十六进制 xxxx规定的 Unicode 字符

    表示字符的方法有多种,除了可以直接使用字符本身外,还可以使用 ASCII 编码或者 Unicode 编码来表示。

    示例1

    下面使用 ASCII 编码定义正则表达式直接量。

    var r = /\x61/;
    var s = "JavaScript";
    var a = s.match(s);
    

    由于字母 a 的 ASCII 编码为 97,被转换为十六进制数值后为 61,因此如果要匹配字符 a,就应该在前面添加“\x”前缀,以提示它为 ASCII 编码。

    示例2

    除了十六进制外,还可以直接使用八进制数值表示字符。

    var r = /\141/;
    var s = "JavaScript";
    var a = s.match(r);
    

    使用十六进制需要添加“\x”前缀,主要是为了避免语义混淆,而八进制则不需要添加前缀。

    示例3

    ASCII 编码只能够匹配有限的单字节字符,使用 Unicode 编码可以表示双字节字符。Unicode 编码方式:“\u”前缀加上 4 位十六进制值。

    var r = "/\u0061/";
    var s = "JavaScript";
    var a = s.match(s);
    

    在 RegExp() 构造函数中使用元字符时,应使用双斜杠。

    var r = new RegExp("\\u0061"); 
    

    RegExp() 构造函数的参数只接受字符串,而不是字符模式。在字符串中,任何字符加反斜杠还表示字符本身,如字符串“\u”就被解释为 u 本身,所以对于“\u0061”字符串来说,在转换为字符模式时,就被解释为“u0061”,而不是“\u0061”,此时反斜杠就失去转义功能。解决方法:在字符 u 前面加双反斜杠。

    4.2 描述字符范围

    在正则表达式语法中,放括号表示字符范围。在方括号中可以包含多个字符,表示匹配其中任意一个字符。如果多个字符的编码顺序是连续的,可以仅指定开头和结尾字符,省略中间字符,仅使用连字符~表示。如果在方括号内添加脱字符^前缀,还可以表示范围之外的字符。例如:

    • [abc]:查找方括号内任意一个字符。
    • [^abc]:查找不在方括号内的字符。
    • [0-9]:查找从 0 至 9 范围内的数字,即查找数字。
    • [a-z]:查找从小写 a 到小写 z 范围内的字符,即查找小写字母。
    • [A-Z]:查找从大写 A 到大写 Z 范围内的字符,即查找大写字母。
    • [A-z]:查找从大写 A 到小写 z 范围内的字符,即所有大小写的字母。

    示例1

    字符范围遵循字符编码的顺序进行匹配。如果将要匹配的字符恰好在字符编码表中特定区域内,就可以使用这种方式表示。

    如果匹配任意 ASCII 字符:

    var r = /[\u0000-\u00ff]/g;
    

    如果匹配任意双字节的汉字:

    var r = /[^\u0000-\u00ff]/g;
    

    如果匹配任意大小写字母和数字:

    var r = /[a-zA-Z0-9]/g;
    

    使用 Unicode 编码设计,匹配数字:

    var r = /[\u0030-\u0039]/g;
    

    使用下面字符模式可以匹配任意大写字母:

    var r = /[\u0041-\u004A]/g;
    

    使用下面字符模式可以匹配任意小写字母:

    var r = /[\u0061-\u007A]/g;
    

    示例2

    在字符范围内可以混用各种字符模式。

    var s = "abcdez";     //字符串直接量
    var r = /[abce-z]/g;  //字符a、b、c,以及从e~z之间的任意字符
    var a = s.match(r);   //返回数组["a","b","c","e","z"]
    

    示例3

    在中括号内不要有空格,否则会误解为还要匹配空格。

    var r = /[0-9]/g;
    

    示例4

    字符范围可以组合使用,以便设计更灵活的匹配模式。

    var s = "abc4 abd6 abe3 abf1 abg7";  //字符串直接量
    var r = /ab[c-g][1-7]/g;             //前两个字符为ab,第三个字符为从c到g,第四个字符为1~7的任意数字
    var a = s.match(r);                  //返回数组["abc4","abd6","abe3","abf1","abg7"]
    

    示例5

    使用反义字符范围可以匹配很多无法直接描述的字符,达到以少应多的目的。

    var r = /[^0123456789]/g;
    

    在这个正则表达式中,将会匹配除了数字以外任意的字符。反义字符类比简单字符类的功能更强大和实用。

    4.3 选择匹配

    选择匹配类似于 JavaScript 的逻辑与运算,使用竖线|描述,表示在两个子模式的匹配结果中任选一个。例如:

    1. 匹配任意数字或字母
    var r = /\w+|\d+/;
    
    1. 可以定义多重选择模式。设计方法:在多个子模式之间加入选择操作符。
    var r = /(abc)|(efg)|(123)|(456)/;
    

    为了避免歧义,应该为选择操作的多个子模式加上小括号。

    示例

    设计对提交的表单字符串进行敏感词过滤。先设计一个敏感词列表,然后使用竖线把它们连接在一起,定义选择匹配模式,最后使用字符串的 replace() 方法把所有敏感字符替换为可以显示的编码格式。代码如下:

    var s = '<meta charset="utf-8">';  //待过滤的表单提交信息
    var r = /\'|\"|\<|\>/gi;  //过滤敏感字符的正则表达式
    function f() {  //替换函数    把敏感字符替换为对应的网页显示的编码格式    
    	return "&#" + arguments[0].charCodeAt(0) + ";";
    }
    var a =s.replace(r,f);  //执行过滤替换 
    document.write(a);  //在网页中显示正常的字符信息
    console.log(a);
    

    显示结果如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nr9fzaIA-1633857087626)(C:\Users\10754\AppData\Roaming\Typora\typora-user-images\image-20211010170548841.png)]

    4.4 重复匹配

    在正则表达式语法中,定义了一组重复类量词,如表所示。它们定义了重复匹配字符的确数或约数。

    量词描述
    n+匹配任何包含至少一个 n 的字符串
    n*匹配任何包含零个或多个 n 的字符串
    n?匹配任何包含零个或一个 n 的字符串
    n{x}匹配包含 x 个 n 的序列的字符串
    n{x,y}匹配包含最少 x 个、最多 y 个 n 的序列的字符串
    n{x,}匹配包含至少 x 个 n 的序列的字符串

    示例

    下面结合示例进行演示说明,先设计一个字符串:

    var s = "ggle gogle google gooogle goooogle gooooogle goooooogle gooooooogle goooooooogle";
    
    1. 如果仅匹配单词 ggle 和 gogle,可以设计:
    var r = /go?gle/g;
    var a = s.match(r);
    

    量词?表示前面字符或子表达式为可有可无,等效于:

    var r = /go{0,1}gle/g;
    var a = s.match(r);
    
    1. 如果匹配第 4 个单词 gooogle,可以设计:
    var r = /go{3}gle/g;
    var a = s.match(r);
    

    等效于:

    var r = /gooogle/g;
    var a = s.match(r);
    
    1. 如果匹配第 4 个到第 6 个之间的单词,可以设计:
    var r = /go{3,5}gle/g;
    var a = s.match(r);
    
    1. 如果匹配所有单词,可以设计:
    var r = /go*gle/g;
    var a = s.match(r);
    

    量词*表示前面字符或表达式可以不出现,或者重复出现任意多次。等效于:

    var r = /go(0,)gle/g;
    var a = s.match(r);
    
    1. 如果匹配包含字符“o”的所有词,可以设计:
    var r = /go+gle/g;
    var a = s.match(r);
    

    量词+表示前面字符或子表达式至少出现 1 次,最多重复次数不限。等效于:

    var r = /go{1,}gle/g;
    var a = s.match(r);
    

    重复类量词总是出现在它们所作用的字符或子表达式后面。如果想作用于多个字符,需要使用小括号把它们包裹在一起形成一个子表达式。

    4.4 惰性匹配

    重复类量词都具有贪婪性,在条件允许的前提下,会匹配尽可能多的字符。

    • ?、{n} 和 {n,m} 重复类具有弱贪婪性,表现为贪婪的有限性。
    • *、+ 和 {n,} 重复类具有强贪婪性,表现为贪婪的无限性。

    示例1

    越是排在左侧的重复类量词匹配优先级越高。下面示例显示当多个重复类量词同时满足条件时,会在保证右侧重复类量词最低匹配次数基础上,使最左侧的重复类量词尽可能占有所有字符。

    var s = "<html><head><title></title></head><body></body></html>";
    var r = /(<.*>)(<.*>)/;
    var a = s.match(r);//左侧表达式匹配
    console.log(a[1]);
    console.log(a[2]);  //右侧表达式匹配“</html>”
    

    与贪婪匹配相反,惰性匹配将遵循另一种算法:在满足条件的前提下,尽可能少的匹配字符。定义惰性匹配的方法:在重复类量词后面添加问号?限制词。贪婪匹配体现了最大化匹配原则,惰性匹配则体现最小化匹配原则。

    示例2

    下面示例演示了如何定义匹配模式。

    var s = "<html><head><title></title></head><body></body></html>";
    var r = /<.*?>/;
    var a = s.match(r);  //返回单个元素数组["<html>"]
    

    在上面示例中,对于正则表达式 /<.*?>/ 来说,它可以返回匹配字符串 “<>”,但是为了能够确保匹配条件成立,在执行中还是匹配了带有 4 个字符的字符串“html”。惰性取值不能够以违反模式限定的条件而返回,除非没有找到符合条件的字符串,否则必须满足它。

    针对 6 种重复类惰性匹配的简单描述如下:

    • {n,m}?:尽量匹配 n 次,但是为了满足限定条件也可能最多重复 m 次。
    • {n}?:尽量匹配 n 次。
    • {n,}?:尽量匹配 n 次,但是为了满足限定条件也可能匹配任意次。
    • ??:尽量匹配,但是为了满足限定条件也可能最多匹配 1 次,相当于 {0,1}?。
    • +?:尽量匹配 1 次,但是为了满足限定条件也可能匹配任意次,相当于 {1,}?。
    • *? :尽量不匹配,但是为了满足限定条件也可能匹配任意次,相当于 {0,}?。

    4.5 边界量词

    边界就是确定匹配模式的位置,如字符串的头部或尾部,具体说明如表所示。

    量词说明
    ^匹配开头,在多行检测中,会匹配一行的开头

    | $ | 匹配结尾,在多行检测中,会匹配一行的结尾
    下面代码演示如何使用边界量词。先定义字符串: |

    var s = "how are you"
    
    1. 匹配最后一个单词
    var r = /\w+$/;
    var a = s.match(r);  //返回数组["you"]
    
    1. 匹配第一个单词
    var r = /^\w+/;
    var a = s.match(r);  //返回数组["how"]
    
    1. 匹配每一个单词
    var r = /\w+/g;
    var a = s.match(r);  //返回数组["how","are","you"]
    

    4.6 声明词量

    声明表示条件的意思。声明词量包括正向声明和反向声明两种模式。

    正向声明

    指定匹配模式后面的字符必须被匹配,但又不返回这些字符。语法格式如下:

    匹配模式 (?= 匹配条件)

    声明包含在小括号内,它不是分组,因此作为子表达式。

    下面代码定义一个正前向生命的匹配模式。

    var s = "one : 1; two : 2";
    var r = /\w*(?==)/;  //使用正前向声明,指定执行匹配必须满足的条件
    var a = s.match(r);  //返回数组["two"]
    

    在上面示例中,通过?==锚定条件,指定只有在 \w* 所能够匹配的字符后面跟随一个等号字符,才能够执行 \w* 匹配。所以,最后匹配的字符串“two”,而不是字符串“one”。

    反向声明

    与正向声明匹配相反,指定接下来的字符都不必被匹配。语法格式如下:

    匹配模式(?! 匹配条件)

    下面代码定义一个反前向生命的匹配模式。

    var s = "one : 1; two : 2";
    var r = /\w*(?!=)/;  //使用正前向声明,指定执行匹配不必满足的条件
    var a = s.match(r);  //返回数组["one"]
    

    在上面示例中,通过?!=锚定条件,指定只有在“\w*”所能够匹配的字符后面不跟随一个等号字符,才能够执行 \w*匹配。所以,最后匹配的是字符串“one”,而不是字符串“two”。

    4.7 子表达式

    使用小括号可以对字符模式进行任意分组,在小括号内的字符串表示子表达式,也称为子模式。子表达式具有独立的匹配功能,保存独立的匹配结果;同时,小括号后的量词将会作用于整个子表达式。

    通过分组可以在一个完整的字符模式中定义一个或多个子模式。当正则表达式成功地匹配目标字符串后,也可以从目标字符串中抽出与子模式相匹配的子内容。

    示例

    在下面代码中,不仅能匹配出每个变量声明,同时还抽出每个变量及其值。

    var s = "ab=21, bc=45, cd=43";
    var r = /(\w+)=(\d*)/g;
    while (a = r.exec(s)) {    
    	console.log(a);  //返回类似["ab=21","bc=45","cd=43"]三个数组
    }
    

    4.8 反向引用

    在字符模式中,后面的字符可以引用前面的子表达式。实现方法如下:

    + 数字

    数字指定了子表达式在字符模式中的顺序。如“\1”引用的是第 1 个子表达式,“\2”引用的是第 2 个子表达式。

    示例1

    在下面代码中,通过引用前面子表达式匹配的文本,实现成组匹配字符串。

    var s = "<h1>title<h1><p>text<p>";
    var r = /(<\/?\w+>)\1/g;
    var a = s.match(r);  //返回数组["<h1>title<h1>","<p>text<p>"]
    

    由于子表达式可以相互嵌套,它们的顺序将根据左括号的顺序来确定。例如,下面示例定义匹配模式包含多个子表达式。

    var s = "abc";
    var r = /(a(b(c)))/;
    var a = s.match(r);  //返回数组["abc","abc","bc","c"]
    

    在这个模式中,共产生了 3 个反向引用,第一个是“(a(b©))”,第二个是“(b©)”,第三个是“©”。它们引用的匹配文本分别是字符串“abc”、“bc”和“c”。

    对子表达式的引用,是指引用前面子表达式所匹配的文本,而不是子表达式的匹配模式。如果要引用前面子表达式的匹配模式,则必须使用下面方式,只有这样才能够达到匹配目的。

    var s = "<h1>title</h1><p>text</p>";
    var r = /((<\/?\w+>).*(<\/?\w+>))/g;
    var a = s.match(r);  //返回数组["<h1>title</h1>","<p>text</p>"]
    

    反向引用在开发中主要有以下几种常规用法。

    示例2

    在正则表达式对象的 test() 方法中,以及字符串对象的 match() 和 search() 等方法中使用。在这些方法中,反向引用的值可以从 RegExp() 构造函数中获得。

    var s = "abcdefghijklmn";
    var r = /(\w)(\w)(\w)/;
    r.test(s);
    console.log(RegExp.$1);  //返回第1个子表达式匹配的字符a
    console.log(RegExp.$2);  //返回第2个子表达式匹配的字符b
    console.log(RegExp.$3);  //返回第3个子表达式匹配的字符c
    

    通过上面示例可以看到,正则表达式执行匹配检测后,所有子表达式匹配的文本都被分组存储在 RegExp() 构造函数的属性内,通过前缀符号$与正则表达式中子表达式的编号来引用这些临时属性。其中属性 $1 标识符指向第 1 个值引用,属性 $2 标识符指向第 2 个值引用。

    示例3

    可以直接在定义的字符模式中包含反向引用。这可以通过使用特殊转义序列(如 \1、\2 等)来实现。

    var s = "abcbcacba";
    var r = /(\w)(\w)(\w)\2\3\1\3\2\1/;
    var b = r.test(s);  //验证正则表达式是否匹配该字符串
    console.log(b);  //返回true
    

    在上面示例的正则表达式中,“\1”表示对第 1 个反向引用 (\w) 所匹配的字符 a 进行引用,“\2”表示对第 2 个反向引用 (\w) 所匹配的字符串 b 进行引用,“\3”表示对第 3 个反向引用 (\w) 所匹配的字符 c 进行引用。

    示例4

    可以在字符串对象的 replace() 方法中使用。通过使用特殊字符序列$1、$2、$3 等来实现。例如,在下面的示例中将颠倒相邻字母和数字的位置。

    var s = "aa11bb22c3d4e5f6";
    var r = /(\w+?)(\d+)/g;
    var b = s.replace(r,"$2$1");
    console.log(b);  //返回字符串“aa11bb22c3  d4e5f6”
    

    在上面例子中,正则表达式包括两个分组,第 1 个分组匹配任意连续的字母,第 2 个分组匹配任意连续的数字。在 replace() 方法的第 2 个参数中,$1 表示对正则表达式中第 1 个子表达式匹配文本的引用,而 $2 表示对正则表达式中第 2 个子表达式匹配文本的引用,通过颠倒 $1 和 $2 标识符的位置,即可实现字符串的颠倒来替换原字符串。

    4.9 禁止引用

    反向引用会占用一定的系统资源,在较长的正则表达式中,反向引用会降低匹配速度。如果分组仅仅是为了方便操作,可以禁止反向引用。

    实现方法:在左括号的后面加上一个问号和冒号。

    var s1 = "abc";
    var r = /(?:\w*?)|(?:\d*?)/;
    var a = r.test(si);
    

    非引用型分组必须使用子表达式,但是又不希望存储无用的匹配信息,或者希望提高匹配速度来说,是非常重用的方法。

    展开全文
  • java正则表达式详解

    万次阅读 多人点赞 2019-04-02 16:35:46
    一、正则表达式术语 1)元字符 : 非一般字符,具有某种意义的字符。如 : \bX : \b边界符, 以 X开始的单词 2)正则表达式语法大全 字符 说明 \ 将下一字符标记为特殊字符...

    微信搜索:“二十同学” 公众号,欢迎关注一条不一样的成长之路

    一、正则表达式术语

     1)元字符 : 非一般字符,具有某种意义的字符。如 : \bX : \b边界符, 以 X开始的单词  

    2)正则表达式语法大全

    字符

    说明

    \

    将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如,"n"匹配字符"n"。"\n"匹配换行符。序列"\\"匹配"\","\("匹配"("。

    ^

    匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与"\n"或"\r"之后的位置匹配。

    $

    匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与"\n"或"\r"之前的位置匹配。

    *

    零次或多次匹配前面的字符或子表达式。例如,zo* 匹配"z"和"zoo"。* 等效于 {0,}。

    +

    一次或多次匹配前面的字符或子表达式。例如,"zo+"与"zo"和"zoo"匹配,但与"z"不匹配。+ 等效于 {1,}。

    ?

    零次或一次匹配前面的字符或子表达式。例如,"do(es)?"匹配"do"或"does"中的"do"。? 等效于 {0,1}。

    {n}

    是非负整数。正好匹配 n 次。例如,"o{2}"与"Bob"中的"o"不匹配,但与"food"中的两个"o"匹配。

    {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,m})之后时,匹配模式是"非贪心的"。"非贪心的"模式匹配搜索到的、尽可能短的字符串,而默认的"贪心的"模式匹配搜索到的、尽可能长的字符串。例如,在字符串"oooo"中,"o+?"只匹配单个"o",而"o+"匹配所有"o"。

    .

    匹配除"\r\n"之外的任何单个字符。若要匹配包括"\r\n"在内的任意字符,请使用诸如"[\s\S]"之类的模式。

    (pattern)

    匹配 pattern 并捕获该匹配的子表达式。可以使用 $0…$9 属性从结果"匹配"集合中检索捕获的匹配。若要匹配括号字符 ( ),请使用"\("或者"\)"。

    (?:pattern)

    匹配 pattern 但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对于用"or"字符 (|) 组合模式部件的情况很有用。例如,'industr(?:y|ies) 是比 'industry|industries' 更经济的表达式。

    (?=pattern)

    执行正向预测先行搜索的子表达式,该表达式匹配处于匹配 pattern 的字符串的起始点的字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows (?=95|98|NT|2000)' 匹配"Windows 2000"中的"Windows",但不匹配"Windows 3.1"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。

    (?!pattern)

    执行反向预测先行搜索的子表达式,该表达式匹配不处于匹配 pattern 的字符串的起始点的搜索字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows (?!95|98|NT|2000)' 匹配"Windows 3.1"中的 "Windows",但不匹配"Windows 2000"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。

    x|y

    匹配 x 或 y。例如,'z|food' 匹配"z"或"food"。'(z|f)ood' 匹配"zood"或"food"。

    [xyz]

    字符集。匹配包含的任一字符。例如,"[abc]"匹配"plain"中的"a"。

    [^xyz]

    反向字符集。匹配未包含的任何字符。例如,"[^abc]"匹配"plain"中"p","l","i","n"。

    [a-z]

    字符范围。匹配指定范围内的任何字符。例如,"[a-z]"匹配"a"到"z"范围内的任何小写字母。

    [^a-z]

    反向范围字符。匹配不在指定的范围内的任何字符。例如,"[^a-z]"匹配任何不在"a"到"z"范围内的任何字符。

    \b

    匹配一个字边界,即字与空格间的位置。例如,"er\b"匹配"never"中的"er",但不匹配"verb"中的"er"。

    \B

    非字边界匹配。"er\B"匹配"verb"中的"er",但不匹配"never"中的"er"。

    \cx

    匹配 x 指示的控制字符。例如,\cM 匹配 Control-M 或回车符。x 的值必须在 A-Z 或 a-z 之间。如果不是这样,则假定 c 就是"c"字符本身。

    \d

    数字字符匹配。等效于 [0-9]。

    \D

    非数字字符匹配。等效于 [^0-9]。

    \f

    换页符匹配。等效于 \x0c 和 \cL。

    \n

    换行符匹配。等效于 \x0a 和 \cJ。

    \r

    匹配一个回车符。等效于 \x0d 和 \cM。

    \s

    匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。

    \S

    匹配任何非空白字符。与 [^ \f\n\r\t\v] 等效。

    \t

    制表符匹配。与 \x09 和 \cI 等效。

    \v

    垂直制表符匹配。与 \x0b 和 \cK 等效。

    \w

    匹配任何字类字符,包括下划线。与"[A-Za-z0-9_]"等效。

    \W

    与任何非单词字符匹配。与"[^A-Za-z0-9_]"等效。

    \xn

    匹配 n,此处的 n 是一个十六进制转义码。十六进制转义码必须正好是两位数长。例如,"\x41"匹配"A"。"\x041"与"\x04"&"1"等效。允许在正则表达式中使用 ASCII 代码。

    \num

    匹配 num,此处的 num 是一个正整数。到捕获匹配的反向引用。例如,"(.)\1"匹配两个连续的相同字符。

    \n

    标识一个八进制转义码或反向引用。如果 \n 前面至少有 n 个捕获子表达式,那么 n 是反向引用。否则,如果 n 是八进制数 (0-7),那么 n 是八进制转义码。

    \nm

    标识一个八进制转义码或反向引用。如果 \nm 前面至少有 nm 个捕获子表达式,那么 nm 是反向引用。如果 \nm 前面至少有 n 个捕获,则 n 是反向引用,后面跟有字符 m。如果两种前面的情况都不存在,则 \nm 匹配八进制值 nm,其中 和 m 是八进制数字 (0-7)。

    \nml

    当 n 是八进制数 (0-3),m 和 l 是八进制数 (0-7) 时,匹配八进制转义码 nml

    \un

    匹配 n,其中 n 是以四位十六进制数表示的 Unicode 字符。例如,\u00A9 匹配版权符号 (©)。

    二、Pattern类与Matcher类详解

            java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包。它包括两个类:Pattern和Matcher Pattern 一个Pattern是一个正则表达式经编译后的表现模式。 Matcher 一个Matcher对象是一个状态机器,它依据Pattern对象做为匹配模式对字符串展开匹配检查。 首先一个Pattern实例订制了一个所用语法与PERL的类似的正则表达式经编译后的模式,然后一个Matcher实例在这个给定的Pattern实例的模式控制下进行字符串的匹配工作。

    以下我们就分别来看看这两个类:

    捕获组的概念

    捕获组可以通过从左到右计算其开括号来编号,编号是从1 开始的。例如,在表达式 ((A)(B(C)))中,存在四个这样的组:

    ((A)(B(C)))
    (A)
    (B(C))
    (C)

    组零始终代表整个表达式。 以 (?) 开头的组是纯的非捕获 组,它不捕获文本,也不针对组合计进行计数。

           与组关联的捕获输入始终是与组最近匹配的子序列。如果由于量化的缘故再次计算了组,则在第二次计算失败时将保留其以前捕获的值(如果有的话)例如,将字符串"aba" 与表达式(a(b)?)+ 相匹配,会将第二组设置为 "b"。在每个匹配的开头,所有捕获的输入都会被丢弃。

    详解Pattern类和Matcher类

           java正则表达式通过java.util.regex包下的Pattern类与Matcher类实现(建议在阅读本文时,打开java API文档,当介绍到哪个方法时,查看java API中的方法说明,效果会更佳). 
           Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不可以直接创建,但可以通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式, 

    Pattern p=Pattern.compile("\\w+"); 
    p.pattern();//返回 \w+ 

    pattern() 返回正则表达式的字符串形式,其实就是返回Pattern.complile(String regex)的regex参数

    1.Pattern.split(CharSequence input)

             Pattern有一个split(CharSequence input)方法,用于分隔字符串,并返回一个String[],我猜String.split(String regex)就是通过Pattern.split(CharSequence input)来实现的. 

    Pattern p=Pattern.compile("\\d+"); 
    String[] str=p.split("我的QQ是:456456我的电话是:0532214我的邮箱是:aaa@aaa.com"); 

    结果:str[0]="我的QQ是:" str[1]="我的电话是:" str[2]="我的邮箱是:aaa@aaa.com" 

    2.Pattern.matcher(String regex,CharSequence input)是一个静态方法,用于快速匹配字符串,该方法适合用于只匹配一次,且匹配全部字符串.

    Pattern.matches("\\d+","2223");//返回true 
    Pattern.matches("\\d+","2223aa");//返回false,需要匹配到所有字符串才能返回true,这里aa不能匹配到 
    Pattern.matches("\\d+","22bb23");//返回false,需要匹配到所有字符串才能返回true,这里bb不能匹配到 

    3.Pattern.matcher(CharSequence input)

             说了这么多,终于轮到Matcher类登场了,Pattern.matcher(CharSequence input)返回一个Matcher对象.
             Matcher类的构造方法也是私有的,不能随意创建,只能通过Pattern.matcher(CharSequence input)方法得到该类的实例. 
             Pattern类只能做一些简单的匹配操作,要想得到更强更便捷的正则匹配操作,那就需要将Pattern与Matcher一起合作.Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持. 

    Pattern p=Pattern.compile("\\d+"); 
    Matcher m=p.matcher("22bb23"); 
    m.pattern();//返回p 也就是返回该Matcher对象是由哪个Pattern对象的创建的 

    4.Matcher.matches()/ Matcher.lookingAt()/ Matcher.find()

            Matcher类提供三个匹配操作方法,三个方法均返回boolean类型,当匹配到时返回true,没匹配到则返回false 
            matches()对整个字符串进行匹配,只有整个字符串都匹配了才返回true 

    Pattern p=Pattern.compile("\\d+"); 
    Matcher m=p.matcher("22bb23"); 
    m.matches();//返回false,因为bb不能被\d+匹配,导致整个字符串匹配未成功. 
    Matcher m2=p.matcher("2223"); 
    m2.matches();//返回true,因为\d+匹配到了整个字符串

           我们现在回头看一下Pattern.matcher(String regex,CharSequence input),它与下面这段代码等价 
    Pattern.compile(regex).matcher(input).matches() 
    lookingAt()对前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true 

    Pattern p=Pattern.compile("\\d+"); 
    Matcher m=p.matcher("22bb23"); 
    m.lookingAt();//返回true,因为\d+匹配到了前面的22 
    Matcher m2=p.matcher("aa2223"); 
    m2.lookingAt();//返回false,因为\d+不能匹配前面的aa 

    find()对字符串进行匹配,匹配到的字符串可以在任何位置. 

    Pattern p=Pattern.compile("\\d+"); 
    Matcher m=p.matcher("22bb23"); 
    m.find();//返回true 
    Matcher m2=p.matcher("aa2223"); 
    m2.find();//返回true 
    Matcher m3=p.matcher("aa2223bb"); 
    m3.find();//返回true 
    Matcher m4=p.matcher("aabb"); 
    m4.find();//返回false 

    5.Mathcer.start()/ Matcher.end()/ Matcher.group()

        当使用matches(),lookingAt(),find()执行匹配操作后,就可以利用以上三个方法得到更详细的信息. 

    • start()返回匹配到的子字符串在字符串中的索引位置. 
    • end()返回匹配到的子字符串的最后一个字符在字符串中的索引位置. 
    • group()返回匹配到的子字符串 
    Pattern p=Pattern.compile("\\d+"); 
    Matcher m=p.matcher("aaa2223bb"); 
    m.find();//匹配2223 
    m.start();//返回3 
    m.end();//返回7,返回的是2223后的索引号 
    m.group();//返回2223 
    
    Mathcer m2=m.matcher("2223bb"); 
    m.lookingAt();   //匹配2223 
    m.start();   //返回0,由于lookingAt()只能匹配前面的字符串,所以当使用lookingAt()匹配时,start()方法总是返回0 
    m.end();   //返回4 
    m.group();   //返回2223 
    
    Matcher m3=m.matcher("2223bb"); 
    m.matches();   //匹配整个字符串 
    m.start();   //返回0,原因相信大家也清楚了 
    m.end();   //返回6,原因相信大家也清楚了,因为matches()需要匹配所有字符串 
    m.group();   //返回2223bb 

            说了这么多,相信大家都明白了以上几个方法的使用,该说说正则表达式的分组在java中是怎么使用的. 
    start(),end(),group()均有一个重载方法它们是start(int i),end(int i),group(int i)专用于分组操作,Mathcer类还有一个groupCount()用于返回有多少组. 

    Pattern p=Pattern.compile("([a-z]+)(\\d+)"); 
    Matcher m=p.matcher("aaa2223bb"); 
    m.find();   //匹配aaa2223 
    m.groupCount();   //返回2,因为有2组 
    m.start(1);   //返回0 返回第一组匹配到的子字符串在字符串中的索引号 
    m.start(2);   //返回3 
    m.end(1);   //返回3 返回第一组匹配到的子字符串的最后一个字符在字符串中的索引位置. 
    m.end(2);   //返回7 
    m.group(1);   //返回aaa,返回第一组匹配到的子字符串 
    m.group(2);   //返回2223,返回第二组匹配到的子字符串 

    现在我们使用一下稍微高级点的正则匹配操作,例如有一段文本,里面有很多数字,而且这些数字是分开的,我们现在要将文本中所有数字都取出来,利用java的正则操作是那么的简单. 
     

    Pattern p=Pattern.compile("\\d+"); 
    Matcher m=p.matcher("我的QQ是:456456 我的电话是:0532214 我的邮箱是:aaa123@aaa.com"); 
    while(m.find()) { 
         System.out.println(m.group()); 
    } 
    
    //输出: 
    
    456456 
    0532214 
    123 
    
    
    //如将以上while()循环替换成 
    
    while(m.find()) { 
         System.out.println(m.group()); 
         System.out.print("start:"+m.start()); 
         System.out.println(" end:"+m.end()); 
    } 
    
    //则输出: 
    
    456456 
    start:6 end:12 
    0532214 
    start:19 end:26 
    123 
    start:36 end:39 

             现在大家应该知道,每次执行匹配操作后start(),end(),group()三个方法的值都会改变,改变成匹配到的子字符串的信息,以及它们的重载方法,也会改变成相应的信息. 
             注意:只有当匹配操作成功,才可以使用start(),end(),group()三个方法,否则会抛出java.lang.IllegalStateException,也就是当matches(),lookingAt(),find()其中任意一个方法返回true时,才可以使用.

    三、常用的正则表达式:

    (1)    "^\d+$"  //非负整数(正整数 + 0)

    (2)    "^[0-9]*[1-9][0-9]*$"  //正整数

    (3)    "^((-\d+)|(0+))$"  //非正整数(负整数 + 0)

    (4)    "^-[0-9]*[1-9][0-9]*$"  //负整数

    (5)    "^-?\d+$"    //整数

    (6)    "^\d+(\.\d+)?$"  //非负浮点数(正浮点数 + 0)

    (7)    "^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$"  //正浮点数

    (8)    "^((-\d+(\.\d+)?)|(0+(\.0+)?))$"  //非正浮点数(负浮点数 + 0)

    (9)    "^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$"  //负浮点数

    (10)  "^(-?\d+)(\.\d+)?$"  //浮点数

    (11)  "^[A-Za-z]+$"  //由26个英文字母组成的字符串

    (12)  "^[A-Z]+$"  //由26个英文字母的大写组成的字符串

    (13)  "^[a-z]+$"  //由26个英文字母的小写组成的字符串

    (14)  "^[A-Za-z0-9]+$"  //由数字和26个英文字母组成的字符串

    (15)  "^\w+$"  //由数字、26个英文字母或者下划线组成的字符串

    (16)  "^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"    //email地址

    (17)  "^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$"  //url

    (18)  /^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))$/   //  年-月-日

    (19)  /^((0([1-9]{1}))|(1[1|2]))/(([0-2]([1-9]{1}))|(3[0|1]))/(d{2}|d{4})$/   // 月/日/年

    (20)  "^([w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$"   //Emil

    (21)  /^((\+?[0-9]{2,4}\-[0-9]{3,4}\-)|([0-9]{3,4}\-))?([0-9]{7,8})(\-[0-9]+)?$/     //电话号码

    (22)  "^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$"   //IP地址

    (23)   

    (24)  匹配中文字符的正则表达式: [\u4e00-\u9fa5]

    (25)  匹配双字节字符(包括汉字在内):[^\x00-\xff]

    (26)  匹配空行的正则表达式:\n[\s| ]*\r

    (27)  匹配HTML标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/

    (28)  匹配首尾空格的正则表达式:(^\s*)|(\s*$)

    (29)  匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

    (30)  匹配网址URL的正则表达式:^[a-zA-z]+://(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$

    (31)  匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$

    (32)  匹配国内电话号码:(\d{3}-|\d{4}-)?(\d{8}|\d{7})?

    (33)  匹配腾讯QQ号:^[1-9]*[1-9][0-9]*$

    (34)  元字符及其在正则表达式上下文中的行为:

    (35)  \ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个后向引用、或一个八进制转义符。

    (36)  ^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的Multiline 属性,^ 也匹配 ’\n’ 或 ’\r’ 之后的位置。

    (37)  $ 匹配输入字符串的结束位置。如果设置了 RegExp 对象的Multiline 属性,$ 也匹配 ’\n’ 或 ’\r’ 之前的位置。

    (38)  * 匹配前面的子表达式零次或多次。

    (39)  + 匹配前面的子表达式一次或多次。+ 等价于 {1,}。

    (40)  ? 匹配前面的子表达式零次或一次。? 等价于 {0,1}。

    (41)  {n} n 是一个非负整数,匹配确定的n 次。

    (42)  {n,} n 是一个非负整数,至少匹配n 次。

    (43)  {n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。在逗号和两个数之间不能有空格。

    (44)  ? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。

    (45)  . 匹配除 "\n" 之外的任何单个字符。要匹配包括 ’\n’ 在内的任何字符,请使用象 ’[.\n]’ 的模式。

    (46)  (pattern) 匹配pattern 并获取这一匹配。

    (47)  (?:pattern) 匹配pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。

    (48)  (?=pattern) 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。

    (49)  (?!pattern) 负向预查,与(?=pattern)作用相反

    (50)  x|y 匹配 x 或 y。

    (51)  [xyz] 字符集合。

    (52)  [^xyz] 负值字符集合。

    (53)  [a-z] 字符范围,匹配指定范围内的任意字符。

    (54)  [^a-z] 负值字符范围,匹配任何不在指定范围内的任意字符。

    (55)  \b 匹配一个单词边界,也就是指单词和空格间的位置。

    (56)  \B 匹配非单词边界。

    (57)  \cx 匹配由x指明的控制字符。

    (58)  \d 匹配一个数字字符。等价于 [0-9]。

    (59)  \D 匹配一个非数字字符。等价于 [^0-9]。

    (60)  \f 匹配一个换页符。等价于 \x0c 和 \cL。

    (61)  \n 匹配一个换行符。等价于 \x0a 和 \cJ。

    (62)  \r 匹配一个回车符。等价于 \x0d 和 \cM。

    (63)  \s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。

    (64)  \S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。

    (65)  \t 匹配一个制表符。等价于 \x09 和 \cI。

    (66)  \v 匹配一个垂直制表符。等价于 \x0b 和 \cK。

    (67)  \w 匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’。

    (68)  \W 匹配任何非单词字符。等价于 ’[^A-Za-z0-9_]’。

    (69)  \xn 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。

    (70)  \num 匹配 num,其中num是一个正整数。对所获取的匹配的引用。

    (71)  \n 标识一个八进制转义值或一个后向引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为后向引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。

    (72)  \nm 标识一个八进制转义值或一个后向引用。如果 \nm 之前至少有is preceded by at least nm 个获取得子表达式,则 nm 为后向引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的后向引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。

    (73)  \nml 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。

    (74)  \un 匹配 n,其中 n 是一个用四个十六进制数字表示的Unicode字符。

    (75)  匹配中文字符的正则表达式: [u4e00-u9fa5]

    (76)  匹配双字节字符(包括汉字在内):[^x00-xff]

    (77)  匹配空行的正则表达式:n[s| ]*r

    (78)  匹配HTML标记的正则表达式:/<(.*)>.*</1>|<(.*) />/

    (79)  匹配首尾空格的正则表达式:(^s*)|(s*$)

    (80)  匹配Email地址的正则表达式:w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*

    (81)  匹配网址URL的正则表达式:http://([w-]+.)+[w-]+(/[w- ./?%&=]*)?

    (82)  利用正则表达式限制网页表单里的文本框输入内容:

    (83)  用正则表达式限制只能输入中文:οnkeyup="value=value.replace(/[^u4E00-u9FA5]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^u4E00-u9FA5]/g,''))"

    (84)  用正则表达式限制只能输入全角字符: οnkeyup="value=value.replace(/[^uFF00-uFFFF]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^uFF00-uFFFF]/g,''))"

    (85)  用正则表达式限制只能输入数字:οnkeyup="value=value.replace(/[^d]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^d]/g,''))"

    (86)  用正则表达式限制只能输入数字和英文:οnkeyup="value=value.replace(/[W]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^d]/g,''))"

    (87)  整理:

    (88)  匹配中文字符的正则表达式: [\u4e00-\u9fa5]

    (89)  匹配双字节字符(包括汉字在内):[^\x00-\xff]

    (90)  匹配空行的正则表达式:\n[\s| ]*\r

    (91)  匹配HTML标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/

    (92)  匹配首尾空格的正则表达式:(^\s*)|(\s*$)

    (93)  匹配IP地址的正则表达式:/(\d+)\.(\d+)\.(\d+)\.(\d+)/g //

    (94)  匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

    (95)  匹配网址URL的正则表达式:http://(/[\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?

    (96)  sql语句:^(select|drop|delete|create|update|insert).*$

    (97)  非负整数:^\d+$

    (98)  正整数:^[0-9]*[1-9][0-9]*$

    (99)  非正整数:^((-\d+)|(0+))$

    (100)  负整数:^-[0-9]*[1-9][0-9]*$

    (101)  整数:^-?\d+$

    (102)  非负浮点数:^\d+(\.\d+)?$

    (103)  正浮点数:^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$

    (104)  非正浮点数:^((-\d+\.\d+)?)|(0+(\.0+)?))$

    (105)  负浮点数:^(-((正浮点数正则式)))$

    (106)  英文字符串:^[A-Za-z]+$

    (107)  英文大写串:^[A-Z]+$

    (108)  英文小写串:^[a-z]+$

    (109)  英文字符数字串:^[A-Za-z0-9]+$

    (110)  英数字加下划线串:^\w+$

    (111)  E-mail地址:^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$

    (112)  URL:^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$

    或:^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$

    (113)  邮政编码:^[1-9]\d{5}$

    (114)  中文:^[\u0391-\uFFE5]+$

    (115)  电话号码:^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$

    (116)  手机号码:^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$

    (117)  双字节字符(包括汉字在内):^\x00-\xff

    (118)  匹配首尾空格:(^\s*)|(\s*$)(像vbscript那样的trim函数)

    (119)  匹配HTML标记:<(.*)>.*<\/\1>|<(.*) \/>

    (120)  匹配空行:\n[\s| ]*\r

    (121)  提取信息中的网络链接:(h|H)(r|R)(e|E)(f|F) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?

    (122)  提取信息中的邮件地址:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

    (123)  提取信息中的图片链接:(s|S)(r|R)(c|C) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?

    (124)  提取信息中的IP地址:(\d+)\.(\d+)\.(\d+)\.(\d+)

    (125)  提取信息中的中国手机号码:(86)*0*13\d{9}

    (126)  提取信息中的中国固定电话号码:(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}

    (127)  提取信息中的中国电话号码(包括移动和固定电话):(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}

    (128)  提取信息中的中国邮政编码:[1-9]{1}(\d+){5}

    (129)  提取信息中的浮点数(即小数):(-?\d*)\.?\d+

    (130)  提取信息中的任何数字 :(-?\d*)(\.\d+)?

    (131)  IP:(\d+)\.(\d+)\.(\d+)\.(\d+)

    (132)  电话区号:/^0\d{2,3}$/

    (133)  腾讯QQ号:^[1-9]*[1-9][0-9]*$

    (134)  帐号(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$

    (135)  中文、英文、数字及下划线:^[\u4e00-\u9fa5_a-zA-Z0-9]+$ 

     

    展开全文
  • PHP中的正则表达式函数 ...PCRE库使用和Perl相同的语法规则实现了正则表达式的模式匹配,其使用以“preg_”为前缀命名的函数。另一套是由POSIX(Portable Operation System interface)扩展库提供的。POSIX扩展

    PHP中的正则表达式函数

    在PHP中有两套正则表达式函数库。一套是由PCRE(Perl Compatible Regular Expression)库提供的。PCRE库使用和Perl相同的语法规则实现了正则表达式的模式匹配,其使用以“preg_”为前缀命名的函数。另一套是由POSIX(Portable Operation System interface)扩展库提供的。POSIX扩展的正则表达式由POSIX 1003.2定义,一般使用以“ereg_”为前缀命名的函数。
    两套函数库的功能相似,执行效率稍有不同。一般而言,实现相同的功能,使用PCRE库的效率略占优势。下面详细介绍其使用方法。


    正则表达式的匹配
    1.preg_match()
    函数原型:int preg_match (string $pattern, string $content [, array $matches])
    preg_match ()函数在$content字符串中搜索与$pattern给出的正则表达式相匹配的内容。如果提供了$matches,则将匹配结果放入其中。$matches[0]将包含与整个模式匹配的文本,$matches[1]将包含第一个捕获的与括号中的模式单元所匹配的内容,以此类推。该函数只作一次匹配,最终返回0或1的匹配结果数。代码6.1给出preg_match()函数的一段代码示例。
    代码6.1  日期时间的匹配
    <?php
         //需要匹配的字符串。date函数返回当前时间
         $content = "Current date and time is ".date("Y-m-d h:i a").", we are learning PHP together.";
         //使用通常的方法匹配时间
         if (preg_match ("/\d{4}-\d{2}-\d{2} \d{2}:\d{2} [ap]m/", $content, $m))
         {
            echo "匹配的时间是:" .$m[0]. "\n";
         }
         //由于时间的模式明显,也可以简单的匹配
         if (preg_match ("/([\d-]{10}) ([\d:]{5} [ap]m)/", $content, $m))
         {
             echo "当前日期是:" .$m[1]. "\n";
             echo "当前时间是:" .$m[2]. "\n";
         }
    ?>
    这是一个简单动态文本串匹配实例。假设当前系统时间是“2006年8月17日13点25分”,将输出如下的内容。
    匹配的时间是:2006-08-17 01:25 pm
    当前日期是:2006-08-17
    当前时间是:01:25 pm
    2.ereg()和eregi()
    ereg()是POSIX扩展库中正则表达式的匹配函数。eregi()是ereg()函数的忽略大小写的版本。二者与preg_match的功能类似,但函数返回的是一个布尔值,表明匹配成功与否。需要说明的是,POSIX扩展库函数的第一个参数接受的是正则表达式字符串,即不需要使用分界符。例如,代码6.2是一个关于文件名安全检验的方法。
    代码6.2  文件名的安全检验
    <?php
         $username = $_SERVER['REMOTE_USER'];
         $filename = $_GET['file'];
         //对文件名进行过滤,以保证系统安全
         if (!ereg('^[^./][^/]*$', $userfile))
         {
             die('这不是一个非法的文件名!');
         }
         //对用户名进行过滤
         if (!ereg('^[^./][^/]*$', $username))
         {
             die('这不是一个无效的用户名');
         }
                   
         //通过安全过滤,拼合文件路径
         $thefile = "/home/$username/$filename";
    ?>
    通常情况下,使用与Perl兼容的正则表达式匹配函数perg_match(),将比使用ereg()或eregi()的速度更快。如果只是查找一个字符串中是否包含某个子字符串,建议使用strstr()或strpos()函数。
    3.preg_grep()
    函数原型:array preg_grep (string $pattern, array $input)
    preg_grep()函数返回一个数组,其中包括了$input数组中与给定的$pattern模式相匹配的单元。对于输入数组$input中的每个元素,preg_grep()也只进行一次匹配。代码6.3给出的示例简单地说明了preg_grep()函数的使用。
    代码6.3  数组查询匹配
    <?php
         $subjects = array(
             "Mechanical Engineering",   "Medicine",
              "Social Science",            "Agriculture",
              "Commercial Science",                           "Politics"
        );
                   
         //匹配所有仅由有一个单词组成的科目名
         $alonewords = preg_grep("/^[a-z]*$/i", $subjects);
    ?>
    6.3.2  进行全局正则表达式匹配
    1.preg_match_all()
    与preg_match()函数类似。如果使用了第三个参数,将把所有可能的匹配结果放入。本函数返回整个模式匹配的次数(可能为0),如果出错返回False。下面是一个将文本中的URL链接地址转换为HTML代码的示例。代码6.4是preg_match_all()函数的使用范例。
    代码6.4  将文本中的链接地址转成HTML
    <?php
         //功能:将文本中的链接地址转成HTML
         //输入:字符串
         //输出:字符串
         function url2html($text)
         {
             //匹配一个URL,直到出现空白为止
             preg_match_all("/http:\/\/?[^\s]+/i", $text, $links);
             //设置页面显示URL地址的长度
             $max_size = 40;
             foreach($links[0] as $link_url)
             {
                 //计算URL的长度。如果超过$max_size的设置,则缩短。
                 $len = strlen($link_url);
                 if($len > $max_size)
                 {
                     $link_text = substr($link_url, 0, $max_size)."...";
                 } else {
                     $link_text = $link_url;
                 }
                 //生成HTML文字
                 $text = str_replace($link_url,"<a href='$link_url'>$link_text</a>",$text);
             }
             return $text;
         }
                   
         //运行实例
         $str = “这是一个包含多个URL链接地址的多行文字。欢迎访问http://www.taoboor.com”;
         print url2html($str);
         /*输出结果
            这是一个包含多个URL链接地址的多行文字。欢迎访问<a href='http://www.taoboor.com'>
             http://www.taoboor.com</a>
         */
    ?&gt;
    2.多行匹配
    仅仅使用POSIX下的正则表式函数,很难进行复杂的匹配操作。例如,对整个文件(尤其是多行文本)进行匹配查找。使用ereg()对此进行操作的一个方法是分行处理。代码6.5的示例演示了ereg()如何将INI文件的参数赋值到数组之中。
    代码6.5  文件内容的多行匹配
    <?php
         $rows = file('php.ini');  //将php.ini文件读到数组中
         //循环遍历
         foreach($rows as $line)
         {
          If(trim($line))
          {
             //将匹配成功的参数写入数组中
             if(eregi("^([a-z0-9_.]*) *=(.*)", $line, $matches))
             {
                $options[$matches[1]] = trim($matches[2]);
             }
             unset($matches);
           }
         }
         //输出参数结果
         print_r($options);
    ?>
    *提示
    这里只是为了方便说明问题。解析一个*.ini文件,最佳方法是使用函数parse_ini_file()。该函数直接将*.ini文件解析到一个大数组中。
    6.3.3  正则表达式的替换
    1.ereg_replace()和eregi_replace()
    函数原型:string ereg_replace (string $pattern, string $replacement, string $string)
                                                                     string eregi_replace (string $pattern, string $replacement, string $string)
    ereg_replace()在$string中搜索模式字符串$pattern,并将所匹配结果替换为$replacement。当$pattern中包含模式单元(或子模式)时,$replacement中形如“\1”或“$1”的位置将依次被这些子模式所匹配的内容替换。而“\0”或“$0”是指整个的匹配字符串的内容。需要注意的是,在双引号中反斜线作为转义符使用,所以必须使用“\\0”,“\\1”的形式。
    eregi_replace()和ereg_replace()的功能一致,只是前者忽略大小写。代码6.6是本函数的应用实例,这段代码演示了如何对程序源代码做简单的清理工作。
    代码6.6  源代码的清理
    <?php
         $lines = file('source.php');                                                                //将文件读入数组中
         for($i=0; $i&lt;count($lines); $i++)
         {
             //将行末以“\\”或“#”开头的注释去掉
             $lines[$i] = eregi_replace("(\/\/|#).*$", "", $lines[$i]);
             //将行末的空白消除
             $lines[$i] = eregi_replace("[ \n\r\t\v\f]*$", "\r\n", $lines[$i]);
         }
         //整理后输出到页面
         echo htmlspecialchars(join("",$lines));
    ?>
    2.preg_replace()
    函数原型:mixed preg_replace (mixed $pattern, mixed $replacement, mixed $subject [, int $limit])
    preg_replace较ereg_replace的功能更加强大。其前三个参数均可以使用数组;第四个参数$limit可以设置替换的次数,默认为全部替换。代码6.7是一个数组替换的应用实例。
    代码6.7  数组替换
    <?php
         //字符串
         $string = "Name: {Name}&lt;br>\nEmail: {Email}<br>\nAddress: {Address}<br>\n";
         //模式
         $patterns =array(
                 "/{Address}/",
                 "/{Name}/",
                 "/{Email}/"
        );
         //替换字串
         $replacements = array (
                 "No.5, Wilson St., New York, U.S.A",
                 "Thomas Ching",
                 "tom@emailaddress.com",
         );
         //输出模式替换结果
         print preg_replace($patterns, $replacements, $string);
    ?&gt;
    输出结果如下。
    Name: Thomas Ching",
    Email: tom@emailaddress.com
    Address: No.5, Wilson St., New York, U.S.A
    在preg_replace的正则表达式中可以使用模式修正符“e”。其作用是将匹配结果用作表达式,并且可以进行重新运算。例如:
    <?php
         $html_body = “&lt;HTML><Body><H1>TEST</H1>My Picture<Img src=”my.gif”></Body></HTML>”;
         //输出结果中HTML标签将全部为小写字母
         echo preg_replace (
                 "/(<\/?)(\w+)([^>]*&gt;)/e",
                 "'\\1'.strtolower('\\2').'\\3'",   //此处的模式变量\\2将被strtolower转换为小写字符
                  $html_body);
    ?&gt;
    *提示
    preg_replace函数使用了Perl兼容正则表达式语法,通常是比ereg_replace更快的替代方案。如果仅对字符串做简单的替换,可以使用str_replace函数。
    6.3.4  正则表达式的拆分
    1.split()和spliti()
    函数原型:array split (string $pattern, string $string [, int $limit])
    本函数返回一个字符串数组,每个单元为$string经正则表达式$pattern作为边界分割出的子串。如果设定了$limit,则返回的数组最多包含$limit个单元。而其中最后一个单元包含了$string中剩余的所有部分。spliti是split的忽略大小版本。代码6.8是一个经常用到关于日期的示例。
    代码6.8  日期的拆分
    <?php
         $date = "08/30/2006";
                   
         //分隔符可以是斜线,点,或横线
         list($month, $day, $year) = split ('[/.-]', $date);
                   
         //输出为另一种时间格式
         echo "Month: $month; Day: $day; Year: $year&lt;br />\n";
    ?&gt;
    2.preg_split()
    本函数与split函数功能一致。代码6.9是一个查找文章中单词数量的示例。
    代码6.9  查找文章中单词数量
    <?php
         $seek  = array();
         $text   = "I have a dream that one day I can make it. So just do it, nothing is impossible!";
                   
         //将字符串按空白,标点符号拆分(每个标点后也可能跟有空格)
         $words = preg_split("/[.,;!\s']\s*/", $text);
         foreach($words as $val)
         {
             $seek[strtolower($val)] ++;
         }
         echo "共有大约" .count($words). "个单词。";
         echo "其中共有" .$seek['i']. "个单词“I”。";
    ?>
    *提示
    preg_split()函数使用了Perl兼容正则表达式语法,通常是比split()更快的替代方案。使用正则表达式的方法分割字符串,可以使用更广泛的分隔字符。例如,上面对日期格式和单词处理的分析。如果仅用某个特定的字符进行分割,建议使用explode()函数,它不调用正则表达式引擎,因此速度是最快的。


    下面是一些讲解和例子,仅供大家参考和修改使用:

    2.    "^\d+$"  //非负整数(正整数 + 0)
    3.    "^[0-9]*[1-9][0-9]*$"  //正整数
    4.    "^((-\d+)|(0+))$"  //非正整数(负整数 + 0)
    5.    "^-[0-9]*[1-9][0-9]*$"  //负整数
    6.    "^-?\d+$"    //整数
    7.    "^\d+(\.\d+)?$"  //非负浮点数(正浮点数 + 0)
    8.    "^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$"  //正浮点数
    9.    "^((-\d+(\.\d+)?)|(0+(\.0+)?))$"  //非正浮点数(负浮点数 + 0)
    10.    "^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$"  //负浮点数
    11.    "^(-?\d+)(\.\d+)?$"  //浮点数
    12.    "^[A-Za-z]+$"  //由26个英文字母组成的字符串
    13.    "^[A-Z]+$"  //由26个英文字母的大写组成的字符串
    14.    "^[a-z]+$"  //由26个英文字母的小写组成的字符串
    15.    "^[A-Za-z0-9]+$"  //由数字和26个英文字母组成的字符串
    16.    "^\w+$"  //由数字、26个英文字母或者下划线组成的字符串
    17.    "^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"    //email地址
    18.    "^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$"  //url
    19.    /^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))$/   //  年-月-日
    20.    /^((0([1-9]{1}))|(1[1|2]))/(([0-2]([1-9]{1}))|(3[0|1]))/(d{2}|d{4})$/   // 月/日/年
    21.    "^([w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$"   //Emil
    22.    /^((\+?[0-9]{2,4}\-[0-9]{3,4}\-)|([0-9]{3,4}\-))?([0-9]{7,8})(\-[0-9]+)?$/     //电话号码
    23.    "^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$"   //IP地址
    24.    
    25.    匹配中文字符的正则表达式: [\u4e00-\u9fa5]
    26.    匹配双字节字符(包括汉字在内):[^\x00-\xff]
    27.    匹配空行的正则表达式:\n[\s| ]*\r
    28.    匹配HTML标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/
    29.    匹配首尾空格的正则表达式:(^\s*)|(\s*$)
    30.    匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
    31.    匹配网址URL的正则表达式:^[a-zA-z]+://(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$
    32.    匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
    33.    匹配国内电话号码:(\d{3}-|\d{4}-)?(\d{8}|\d{7})?
    34.    匹配腾讯QQ号:^[1-9]*[1-9][0-9]*$
    35.    
    36.    
    37.    元字符及其在正则表达式上下文中的行为:
    38.    
    39.    \ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个后向引用、或一个八进制转义符。
    40.    
    41.    ^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的Multiline 属性,^ 也匹配 ’\n’ 或 ’\r’ 之后的位置。
    42.    
    43.    $ 匹配输入字符串的结束位置。如果设置了 RegExp 对象的Multiline 属性,$ 也匹配 ’\n’ 或 ’\r’ 之前的位置。
    44.    
    45.    * 匹配前面的子表达式零次或多次。
    46.    
    47.    + 匹配前面的子表达式一次或多次。+ 等价于 {1,}。
    48.    
    49.    ? 匹配前面的子表达式零次或一次。? 等价于 {0,1}。
    50.    
    51.    {n} n 是一个非负整数,匹配确定的n 次。
    52.    
    53.    {n,} n 是一个非负整数,至少匹配n 次。
    54.    
    55.    {n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。在逗号和两个数之间不能有空格。
    56.    
    57.    ? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。
    58.    
    59.    . 匹配除 "\n" 之外的任何单个字符。要匹配包括 ’\n’ 在内的任何字符,请使用象 ’[.\n]’ 的模式。
    60.    (pattern) 匹配pattern 并获取这一匹配。
    61.    
    62.    (?:pattern) 匹配pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。
    63.    
    64.    (?=pattern) 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。
    65.    
    66.    (?!pattern) 负向预查,与(?=pattern)作用相反
    67.    
    68.    x|y 匹配 x 或 y。
    69.    
    70.    [xyz] 字符集合。
    71.    
    72.    [^xyz] 负值字符集合。
    73.    
    74.    [a-z] 字符范围,匹配指定范围内的任意字符。
    75.    
    76.    [^a-z] 负值字符范围,匹配任何不在指定范围内的任意字符。
    77.    
    78.    \b 匹配一个单词边界,也就是指单词和空格间的位置。
    79.    
    80.    \B 匹配非单词边界。
    81.    
    82.    \cx 匹配由x指明的控制字符。
    83.    
    84.    \d 匹配一个数字字符。等价于 [0-9]。
    85.    
    86.    \D 匹配一个非数字字符。等价于 [^0-9]。
    87.    
    88.    \f 匹配一个换页符。等价于 \x0c 和 \cL。
    89.    
    90.    \n 匹配一个换行符。等价于 \x0a 和 \cJ。
    91.    
    92.    \r 匹配一个回车符。等价于 \x0d 和 \cM。
    93.    
    94.    \s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。
    95.    
    96.    \S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
    97.    
    98.    \t 匹配一个制表符。等价于 \x09 和 \cI。
    99.    
    100.    \v 匹配一个垂直制表符。等价于 \x0b 和 \cK。
    101.    
    102.    \w 匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’。
    103.    
    104.    \W 匹配任何非单词字符。等价于 ’[^A-Za-z0-9_]’。
    105.    
    106.    \xn 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。
    107.    
    108.    \num 匹配 num,其中num是一个正整数。对所获取的匹配的引用。
    109.    
    110.    \n 标识一个八进制转义值或一个后向引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为后向引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。
    111.    
    112.    \nm 标识一个八进制转义值或一个后向引用。如果 \nm 之前至少有is preceded by at least nm 个获取得子表达式,则 nm 为后向引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的后向引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。
    113.    
    114.    \nml 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。
    115.    
    116.    \un 匹配 n,其中 n 是一个用四个十六进制数字表示的Unicode字符。
    117.    
    118.    匹配中文字符的正则表达式: [u4e00-u9fa5]
    119.    
    120.    匹配双字节字符(包括汉字在内):[^x00-xff]
    121.    
    122.    匹配空行的正则表达式:n[s| ]*r
    123.    
    124.    匹配HTML标记的正则表达式:/<(.*)>.*</1>|<(.*) />/
    125.    
    126.    匹配首尾空格的正则表达式:(^s*)|(s*$)
    127.    
    128.    匹配Email地址的正则表达式:w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*
    129.    
    130.    匹配网址URL的正则表达式:http://([w-]+.)+[w-]+(/[w- ./?%&=]*)?
    131.    
    132.    利用正则表达式限制网页表单里的文本框输入内容:
    133.    
    134.    用正则表达式限制只能输入中文:οnkeyup="value=value.replace(/[^u4E00-u9FA5]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^u4E00-u9FA5]/g,''))"
    135.    
    136.    用正则表达式限制只能输入全角字符: οnkeyup="value=value.replace(/[^uFF00-uFFFF]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^uFF00-uFFFF]/g,''))"
    137.    
    138.    用正则表达式限制只能输入数字:οnkeyup="value=value.replace(/[^d]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^d]/g,''))"
    139.    
    140.    用正则表达式限制只能输入数字和英文:οnkeyup="value=value.replace(/[W]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^d]/g,''))"
    141.    
    142.    =========常用正则式
    143.    
    144.    
    145.    
    146.    匹配中文字符的正则表达式: [\u4e00-\u9fa5]
    147.    
    148.    匹配双字节字符(包括汉字在内):[^\x00-\xff]
    149.    
    150.    匹配空行的正则表达式:\n[\s| ]*\r
    151.    
    152.    匹配HTML标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/
    153.    
    154.    匹配首尾空格的正则表达式:(^\s*)|(\s*$)
    155.    
    156.    匹配IP地址的正则表达式:/(\d+)\.(\d+)\.(\d+)\.(\d+)/g //
    157.    
    158.    匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
    159.    
    160.    匹配网址URL的正则表达式:http://(/[\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?
    161.    
    162.    sql语句:^(select|drop|delete|create|update|insert).*$
    163.    
    164.    1、非负整数:^\d+$
    165.    
    166.    2、正整数:^[0-9]*[1-9][0-9]*$
    167.    
    168.    3、非正整数:^((-\d+)|(0+))$
    169.    
    170.    4、负整数:^-[0-9]*[1-9][0-9]*$
    171.    
    172.    5、整数:^-?\d+$
    173.    
    174.    6、非负浮点数:^\d+(\.\d+)?$
    175.    
    176.    7、正浮点数:^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
    177.    
    178.    8、非正浮点数:^((-\d+\.\d+)?)|(0+(\.0+)?))$
    179.    
    180.    9、负浮点数:^(-((正浮点数正则式)))$
    181.    
    182.    10、英文字符串:^[A-Za-z]+$
    183.    
    184.    11、英文大写串:^[A-Z]+$
    185.    
    186.    12、英文小写串:^[a-z]+$
    187.    
    188.    13、英文字符数字串:^[A-Za-z0-9]+$
    189.    
    190.    14、英数字加下划线串:^\w+$
    191.    
    192.    15、E-mail地址:^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$
    193.    
    194.    16、URL:^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$
    195.    或:^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$
    196.    
    197.    17、邮政编码:^[1-9]\d{5}$
    198.    
    199.    18、中文:^[\u0391-\uFFE5]+$
    200.    
    201.    19、电话号码:^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$
    202.    
    203.    20、手机号码:^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$
    204.    
    205.    21、双字节字符(包括汉字在内):^\x00-\xff
    206.    
    207.    22、匹配首尾空格:(^\s*)|(\s*$)(像vbscript那样的trim函数)
    208.    
    209.    23、匹配HTML标记:<(.*)>.*<\/\1>|<(.*) \/>
    210.    
    211.    24、匹配空行:\n[\s| ]*\r
    212.    
    213.    25、提取信息中的网络链接:(h|H)(r|R)(e|E)(f|F) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?
    214.    
    215.    26、提取信息中的邮件地址:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
    216.    
    217.    27、提取信息中的图片链接:(s|S)(r|R)(c|C) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?
    218.    
    219.    28、提取信息中的IP地址:(\d+)\.(\d+)\.(\d+)\.(\d+)
    220.    
    221.    29、提取信息中的中国手机号码:(86)*0*13\d{9}
    222.    
    223.    30、提取信息中的中国固定电话号码:(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}
    224.    
    225.    31、提取信息中的中国电话号码(包括移动和固定电话):(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}
    226.    
    227.    32、提取信息中的中国邮政编码:[1-9]{1}(\d+){5}
    228.    
    229.    33、提取信息中的浮点数(即小数):(-?\d*)\.?\d+
    230.    
    231.    34、提取信息中的任何数字 :(-?\d*)(\.\d+)?
    232.    
    233.    35、IP:(\d+)\.(\d+)\.(\d+)\.(\d+)
    234.    
    235.    36、电话区号:/^0\d{2,3}$/
    236.    
    237.    37、腾讯QQ号:^[1-9]*[1-9][0-9]*$
    238.    
    239.    38、帐号(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
    240.    

    241.    39、中文、英文、数字及下划线:^[\u4e00-\u9fa5_a-zA-Z0-9]+$





    js正则函数match、exec、test、search、replace、split使用介绍集合

    js:    pattern = /\-+.*/

             pattern.test(’你的字符‘)        返回bool值

             pattern.exec('你的字符')       返回数组

             str.replace(param1,param2)     注意这里的param1可以是直接的字符也可以是正则表达式,   param2是你要替换成的字符        一定要注意是有返回值的你的最终替换结    果是返回值


    以下为一些方法的详细介绍:

    match 方法
    使用正则表达式模式对字符串执行查找,并将包含查找的结果作为数组返回。
    stringObj.match(rgExp)
    参数
    stringObj
    必选项。对其进行查找的 String 对象或字符串文字。
    rgExp
    必选项。为包含正则表达式模式和可用标志的正则表达式对象。也可以是包含正则表达式模式和可用标志的变量名或字符串文字。
    其余说明与exec一样,不同的是如果match的表达式匹配了全局标记g将出现所有匹配项,而不用循环,但所有匹配中不会包含子匹配项。
    例子1:
    function MatchDemo(){ var r, re; // 声明变量。 var s = "The rain in Spain falls mainly in the plain"; re = /(a)in/ig; // 创建正则表达式模式。 r = s.match(re); // 尝试去匹配搜索字符串。 document.write(r); // 返回的数组包含了所有 "ain" 出现的四个匹配,r[0]、r[1]、r[2]、r[3]。 // 但没有子匹配项a。}输出结果:ain,ain,ain,ain


    exec 方法

    用正则表达式模式在字符串中查找,并返回该查找结果的第一个值(数组),如果匹配失败,返回null。
    rgExp.exec(str)
    参数
    rgExp
    必选项。包含正则表达式模式和可用标志的正则表达式对象。
    str
    必选项。要在其中执行查找的 String 对象或字符串文字。
    返回数组包含:
    input:整个被查找的字符串的值;
    index:匹配结果所在的位置(位);
    lastInput:下一次匹配结果的位置;
    arr:结果值,arr[0]全匹配结果,arr[1,2...]为表达式内()的子匹配,由左至右为1,2...。
    例子2:
    代码如下:

    function RegExpTest(){
    var src="http://sumsung753.blog.163.com/blog/I love you!";
    var re = /\w+/g; // 注意g将全文匹配,不加将永远只返回第一个匹配。
    var arr;
    while((arr = re.exec(src)) !=null){ //exec使arr返回匹配的第一个,while循环一次将使re在g作用寻找下一个匹配。
    document.write(arr.index + "-" + arr.lastIndex + ":" + arr + "<br/>");
    for(key in arr){
    document.write(key + "=>" + arr[key] + "<br/>");
    }
    document.write("<br/>");
    }
    }
    window.onload = RegExpTest();

    输出结果:
    0-1:I //0为index,i所在位置,1为下一个匹配所在位置
    input=>I love you!
    index=>0
    lastIndex=>1
    0=>I
    2-6:love
    input=>I love you!
    index=>2
    lastIndex=>6
    0=>love
    7-10:you
    input=>I love you!
    index=>7
    lastIndex=>10
    0=>you
    说明:根据手册,exec只返回匹配结果的第一个值,比如上例如果不用while循环,将只返回'I'(尽管i空格后的love和you都符合表达式),无论re表达式用不用全局标记g。但是如果为正则表达式设置了全局标记g,exec 从以 lastIndex 的值指示的位置开始查找。如果没有设置全局标志,exec 忽略 lastIndex 的值,从字符串的起始位置开始搜索。利用这个特点可以反复调用exec遍历所有匹配,等价于match具有g标志。
    当然,如果正则表达式忘记用g,而又用循环(比如:while、for等),exec将每次都循环第一个,造成死循环。
    exec的输出将包含子匹配项。
    例子3:
    代码如下:

    function execDemo(){
    var r, re; // 声明变量。
    var s = "The rain in Spain falls mainly in the plain";
    re = /[\w]*(ai)n/ig;
    r = re.exec(s);
    document.write(r + "<br/>");
    for(key in r){
    document.write(key + "-" + r[key] + "<br/>");
    }
    }
    window.onload = execDemo();

    输出:
    rain,ai
    input-The rain in Spain falls mainly in the plain
    index-4
    lastIndex-8
    0-rain
    1-ai



    test 方法

    返回一个 Boolean 值,它指出在被查找的字符串中是否匹配给出的正则表达式。
    rgexp.test(str)
    参数
    rgexp
    必选项。包含正则表达式模式或可用标志的正则表达式对象。
    str
    必选项。要在其上测试查找的字符串。
    说明
    test 方法检查字符串是否与给出的正则表达式模式相匹配,如果是则返回 true,否则就返回 false。
    例子4:
    代码如下:

    function TestDemo(re, s){
    var s1;
    if (re.test(s))
    s1 = " 匹配正则式 ";
    else
    s1 = " 不匹配正则式 ";
    return("'" + s + "'" + s1 + "'"+ re.source + "'");
    }
    window.onload = document.write(TestDemo(/ab/,'cdef'));

    输出结果:'cdef' 不匹配正则式 'ab'
    注意:test()继承正则表达式的lastIndex属性,表达式在匹配全局标志g的时候须注意。
    例子5:
    代码如下:

    function testDemo(){
    var r, re; // 声明变量。
    var s = "I";
    re = /I/ig; // 创建正则表达式模式。
    document.write(re.test(s) + "<br/>"); // 返回 Boolean 结果。
    document.write(re.test(s) + "<br/>");
    document.write(re.test(s));
    }
    testDemo();

    输出结果:
    true
    false
    true
    当第二次调用test()的时候,lastIndex指向下一次匹配所在位置1,所以第二次匹配不成功,lastIndex重新指向0,等于第三次又重新匹配。下例显示test的lastIndex属性:
    例子6:
    代码如下:

    function testDemo(){
    var r, re; // 声明变量。
    var s = "I";
    re = /I/ig; // 创建正则表达式模式。
    document.write(re.test(s) + "<br/>"); // 返回 Boolean 结果。
    document.write(re.lastIndex); // 返回 Boolean 结果。
    }
    testDemo();

    输出:
    true
    1
    解决方法:将test()的lastIndex属性每次重新指向0,re.lastIndex = 0;



    search 方法

    返回与正则表达式查找内容匹配的第一个子字符串的位置(偏移位)。
    stringObj.search(rgExp)
    参数
    stringObj
    必选项。要在其上进行查找的 String 对象或字符串文字。
    rgExp
    必选项。包含正则表达式模式和可用标志的正则表达式对象。
    说明:如果找到则返回子字符至开始处的偏移位,否则返回-1。
    例子6:
    代码如下:

    function SearchDemo(){
    var r, re; // 声明变量。
    var s = "The rain in Spain falls mainly in the plain.";
    re = /falls/i; // 创建正则表达式模式。
    re2 = /tom/i;
    r = s.search(re); // 查找字符串。
    r2 = s.search(re2);
    return("r:" + r + ";r2:" + r2); // 返回 Boolean 结果。
    }
    document.write(SearchDemo());

    输出:r:18;r2:-1



    replace 方法
    返回根据正则表达式进行文字替换后的字符串的复制。
    stringObj.replace(rgExp, replaceText)
    参数
    stringObj
    必选项。要执行该替换的 String 对象或字符串文字。该字符串不会被 replace 方法修改。
    rgExp
    必选项。为包含正则表达式模式或可用标志的正则表达式对象。也可以是 String 对象或文字。如果 rgExp 不是正则表达式对象,它将被转换为字符串,并进行精确的查找;不要尝试将字符串转化为正则表达式。
    replaceText
    必选项。是一个String 对象或字符串文字,对于stringObj 中每个匹配 rgExp 中的位置都用该对象所包含的文字加以替换。在 Jscript 5.5 或更新版本中,replaceText 参数也可以是返回替换文本的函数。
    说明
    replace 方法的结果是一个完成了指定替换的 stringObj 对象的复制。意思为匹配的项进行指定替换,其它不变作为StringObj的原样返回。
    ECMAScript v3 规定,replace() 方法的参数 replacement 可以是函数而不是字符串。在这种情况下,每个匹配都调用该函数,它返回的字符串将作为替换文本使用。该函数的第一个参数是匹配模式的字符串。接下来的参数是与模式中的子表达式匹配的字符串,可以有 0 个或多个这样的参数。接下来的参数是一个整数,声明了匹配在 stringObject 中出现的位置。最后一个参数是 stringObject 本身。结果为将每一匹配的子字符串替换为函数调用的相应返回值的字符串值。函数作参可以进行更为复杂的操作。
    例子7:
    代码如下:

    function f2c(s) {
    var test = /(\d+(\.\d*)?)F\b/g; // 说明华氏温度可能模式有:123F或123.4F。注意,这里用了g模式
    return(s.replace
    (test,
    function(Regstr,$1,$2,$3,newstrObj) {
    return(("<br/>" + Regstr +"<br/>" + ($1-32) * 1/2) + "C" +"<br/>" + //以下两行进行替换
    $2 +"<br/>" + $3 +"<br/>" + newstrObj +"<br/>" );
    }
    )
    );
    }
    document.write(f2c("Water: 32.2F and Oil: 20.30F."));

    输出结果:
    Water: //不与正则匹配的字符,按原字符输出
    32.2F //与正则相匹配的第一个字符串的原字符串 Regstr
    0.10000000000000142C //与正则相匹配的第一个字符串的第一个子模式匹配的替换结果 $1
    .2 //与正则相匹配的第一个字符串的第二个子模式匹配项的替换结果,这里我们没有将它替换 $2
    7 //与正则相匹配的第一个字符串的第一个子匹配出现的偏移量 $3
    Water: 32.2F and Oil: 20.30F. //原字符串 newstrObj
    and Oil: //不与正则匹配的字符
    20.30F //与正则相匹配的第二个字符串的原字符串
    -5.85C //与正则相匹配的第二个字符串的第一个子模式与匹配的替换结果
    .30 //与正则相匹配的第二个字符串的第二个子模式匹配项的替换结果,这里我们没有将它替换
    22 //与正则相匹配的第二个字符串的第一个子匹配出现的偏移量
    Water: 32.2F and Oil: 20.30F. //原字符串
    . //不与正则匹配的字符
    上面的函数参数我们全部用到了。在实际中,我们只须用将xxF替换为xxC,根据要求,我们无须写这么多参数。
    例子8:
    代码如下:

    function f2c(s) {
    var test = /(\d+(\.\d*)?)F\b/g; // 说明华氏温度可能模式有:123F或123.4F
    return(s.replace
    (test,
    function(strObj,$1) {
    return((($1-32) * 1/2) + "C");
    }
    )
    );
    }
    document.write(f2c("Water: 32.2F and Oil: 20.30F."));

    输出:Water: 0.10000000000000142C and Oil: -5.85C.
    更多的应用:
    例子9:
    代码如下:

    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 方法
    将一个字符串分割为子字符串,然后将结果作为字符串数组返回。
    stringObj.split([separator[, limit]])
    参数
    stringObj
    必选项。要被分解的 String 对象或文字。该对象不会被 split 方法修改。
    separator
    可选项。字符串或 正则表达式 对象,它标识了分隔字符串时使用的是一个还是多个字符。如果忽略该选项,返回包含整个字符串的单一元素数组。
    limit
    可选项。该值用来限制返回数组中的元素个数。
    说明
    split 方法的结果是一个字符串数组,在 stingObj 中每个出现 separator 的位置都要进行分解。separator 不作为任何数组元素的部分返回。
    例子10:
    代码如下:

    function SplitDemo(){
    var s, ss;
    var s = "The rain in Spain falls mainly in the plain.";
    // 正则表达式,用不分大不写的s进行分隔。
    ss = s.split(/s/i);
    return(ss);
    }
    document.write(SplitDemo());

    输出:The rain in ,pain fall, mainly in the plain.

    js正则表达式之exec()方法、match()方法以及search()方法

    先看代码:

    var sToMatch = "test, Tes, tst, tset, Test, Tesyt, sTes";
    var reEs = /es/gi;
    alert(reEs.exec(sToMatch));
    alert(sToMatch.match(reEs));
    alert(sToMatch.search(reEs));

    三个弹出框内容如下:

    结果分析如下:

    1、RegExp的exec()方法,有一个字符串参数,返回一个数组,数组的第一个条目是第一个匹配;其他的是反向引用。所以第一个返回的结果是第一个匹配的值es(不区分大小写)。

    2、String对象有一个match()方法,它返回一个包含在字符串中所有匹配的数据。这个方法调用string对象,同时传给它一个RegExp对象。所以第二个弹出语句返回的是所有符合正则表达式的数组。

    3、search()的字符串方法与indexOf()有些类似,但是它使用一个RegExp对象而非仅仅一个子字符串。search()方法返回第一个匹配值的位置。所以第三处弹出的是“1”,即第二个字符就匹配了。注意的是search()方法不支持全局匹配正规表达式(带参数g)。

    展开全文
  • 在实际开发过程中经常会有查找符合某些复杂规则的字符串的需要,比如:邮箱、图片地址、手机号码等,这时候想匹配或者查找符合某些规则的字符串就可以使用正则表达式了。 2. 正则表达式概念 正则表达式就是记录文本...

    正则表达式的概述

    学习目标

    • 能够知道正则表达式的作用

    1. 正则表达式的介绍

    在实际开发过程中经常会有查找符合某些复杂规则的字符串的需要,比如:邮箱、图片地址、手机号码等,这时候想匹配或者查找符合某些规则的字符串就可以使用正则表达式了。

    2. 正则表达式概念

    正则表达式就是记录文本规则的代码

    3. 正则表达式的样子

    0\d{2}-\d{8} 这个就是一个正则表达式,表达的意思是匹配的是座机号码

    4. 正则表达式的特点

    • 正则表达式的语法很令人头疼,可读性差
    • 正则表达式通用行很强,能够适用于很多编程语言

    5. 小结

    • 正则表达式是匹配符合某些规则的字符串数据

    re模块介绍

    学习目标

    • 能够知道在python中使用正则表达式需要导入的模块

    1. re模块的介绍

    在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用一个 re 模块

    # 导入re模块
    import re
    
    # 使用match方法进行匹配操作
    result = re.match(正则表达式,要匹配的字符串)
    
    # 如果上一步匹配到数据的话,可以使用group方法来提取数据
    result.group()
    

    2. re模块的使用

    import re
    
    
    # 使用match方法进行匹配操作
    result = re.match("itcast","itcast.cn")
    # 获取匹配结果
    info = result.group()
    print(info)
    

    运行结果:

    itcast
    

    3. 小结

    • re.match() 根据正则表达式从头开始匹配字符串数据

    匹配多个字符

    学习目标

    • 能够使用re模块匹配多个字符

    1. 匹配多个字符

    代码功能
    *匹配前一个字符出现0次或者无限次,即可有可无
    +匹配前一个字符出现1次或者无限次,即至少有1次
    ?匹配前一个字符出现1次或者0次,即要么有1次,要么没有
    {m}匹配前一个字符出现m次
    {m,n}匹配前一个字符出现从m到n次

    示例1:*

    需求:匹配出一个字符串第一个字母为大小字符,后面都是小写字母并且这些小写字母可
    有可无

    import re
    
    ret = re.match("[A-Z][a-z]*","M")
    print(ret.group())
    
    ret = re.match("[A-Z][a-z]*","MnnM")
    print(ret.group())
    
    ret = re.match("[A-Z][a-z]*","Aabcdef")
    print(ret.group())
    
    

    运行结果:

    M
    Mnn
    Aabcdef
    

    示例2:+

    需求:匹配一个字符串,第一个字符是t,最后一个字符串是o,中间至少有一个字符

    import re
    
    
    match_obj = re.match("t.+o", "two")
    if match_obj:
        print(match_obj.group())
    else:
        print("匹配失败")
    
    

    运行结果:

    two
    

    示例3:?

    需求:匹配出这样的数据,但是https 这个s可能有,也可能是http 这个s没有

    
    import re
    
    match_obj = re.match("https?", "http")
    if match_obj:
        print(match_obj.group())
    else:
        print("匹配失败")
    
    

    运行结果:

    https
    

    示例4:{m}、{m,n}

    需求:匹配出,8到20位的密码,可以是大小写英文字母、数字、下划线

    import re
    
    
    ret = re.match("[a-zA-Z0-9_]{6}","12a3g45678")
    print(ret.group())
    
    ret = re.match("[a-zA-Z0-9_]{8,20}","1ad12f23s34455ff66")
    print(ret.group())
    
    

    运行结果:

    
    12a3g4
    1ad12f23s34455ff66
    

    2. 小结

    • *表示匹配前一个字符出现0次或者无限次,即可有可无
    • +表示匹配前一个字符出现1次或者无限次,即至少有1次
    • ?表示匹配前一个字符出现1次或者0次,即要么有1次,要么没有
    • {m}表示匹配前一个字符出现m次
    • {m,n}表示匹配前一个字符出现从m到n次
    print("如果文章对你有用,请点个赞呗O(∩_∩)O~")
    
    System.out.println("如果文章对你有用,请点个赞呗O(∩_∩)O~");
    
    cout<<"如果文章对你有用,请点个赞呗O(∩_∩)O~"<<endl;
    
    展开全文
  • 正则表达式

    万次阅读 多人点赞 2019-08-26 16:21:48
    文章目录正则表达式简介正则表达式匹配规则re模块compile 函数Pattern 对象Match 对象范例常见格式分组位置分组分割批量替换正则案例: 正则表达式简介 为什么要学正则表达式? 实际上爬虫一共就四个主要步骤: ...
  • 1.了解正则表达式正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是用来...
  • 正则表达式 1.在实际开发过程中经常会有查找符合某些复杂规则的字符串的需要,比如:邮箱、图片地址、手机号码等, 这时候想匹配或者查找符合某些规则的字符串就可以使用正则表达式了。 正则表达式概念 正则表达式...
  • java 正则表达式 替换 html[2021-01-29 22:37:07]简介:java正则表达式用法:1、使用Pattern类进行字符串...相关免费学习推荐:javaphp正则表达式替换图片地址的方法:首先PHP正则提取图片img标记中的任意属性;然后...
  • 1.了解正则表达式正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是用来...
  • 1,概述给定一个正则表达式和另...这里写图片描述2,正则表达式匹配规则这里写图片描述3,Python 中 re 模块知识1,re 模块的一般使用步骤如下:1,使用 compile() 函数将正则表达式的字符串形式编译为一个 Pattern ...
  • 主要介绍了php使用正则表达式获取图片url的方法,涉及正则匹配的相关技巧,需要的朋友可以参考下
  • 什么是PHP正则表达式?php正则表达式是一种描述字符串...正则表达式是用于描述字符排列和匹配模式的一种语法规则。它主要用于字符串的模式分割、匹配、查找及替换操作。 1. 用途:匹配、查找、替换、分割 2. php提供...
  • C#中获取匹配正则表达式的字符

    千次阅读 2015-04-18 21:40:30
    一、如果字符串中只有一处匹配正则表达式,可用Result来获取匹配字。 例如:  string tmpUrl = "http://sports.163.com/nba/";  Regex r = new Regex(@"^http://(?[^/]+)/", RegexOptions.Compiled);  realUrl...
  • 正则表达式 / Regular Expression 目录 正则表达式模式 re 模块简介 使用正则表达式进行匹配 正则表达式RE(Regular Expression, Regexp, Regex),又称为正规表示法,正规表达式,规则表达式,常规...
  • 正则表达式的组成及在Java中常见正则表达式的用法本文介绍一下正则表达式的组成及在Java中常见正则表达式的用法正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作...
  • 1. 正则表达式语法 使用工具 :RegexBuddy.exe 正则匹配 1. 标准字符集合 \n: 换行符 \t: 制表符 \\ \^ \$: 需要特殊转义的 \d : 数字 0-9 任意一个数字 \D : 非数字 \w : 字母 A-Z,a-z,_ 任意一个字母或...
  • 主要针对正则表达式对标签的两种处理方法,一种是对转换成不含有html标记的普通字符串,另一种是把转好的普通字符串转回标签。方法为作者原创,欢迎转载
  • php正则表达式中的非贪婪模式匹配一般情况下,正则表达式的匹配是贪婪模式的,比如下面这个例子:字符串:....src="http://www.bloghome.cn/1.mp3"type="application/x-mplayer2"....要求的结果:...
  • 发现还有个榜单,里面有各种经典和热映电影的排行榜,然后我觉得电影封面图还挺好看的,想着一张一张下载真是费时费力,于是突发奇想,好像可以用一下最近学的东西实现我的需求,学习了正则表达式之后,想着要感受...
  • 主要介绍了java正则表达式解析html示例,用到获取url的正则表达式,获取图片正则表达式,需要的朋友可以参考下
  • 主要介绍了使用C#正则表达式获取必应每日图片地址的相关资料,需要的朋友可以参考下
  • 目录:一、得到要爬取的url二、拿到网页源码三、得到图片链接四、保存图片五、拓展在上一篇文章我们介绍了正则表达式的用法,这次就来实际操作一下正则表达式。这次要爬取的是百度图片,我们应该有一个大概的思路:...
  • python正则表达式

    2019-04-14 19:43:17
    Python正则表达式模块2.1 正则表达式处理字符串主要有四大功能2.2 Python中re模块使用正则表达式的两种方法2.3 正则表达式对象的常用方法2.4 匹配对象的属性与方法2.5 总结 1 正则表达式语法 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 52,098
精华内容 20,839
关键字:

获取图片的正则表达式