在构造和理解正则表达式的过程中,通常都是由简到繁的过程,如果理解正则表达式内部间的关系,就可以把比较复杂的正则表达式拆分成几个小块来理解,从而帮助消化。

正则表达式的逻辑关系

正则表达式之间的逻辑关系可以简单地用与、或、非来描述,如表所示。

通常来说,正则表达式可以看做这三种逻辑关系的组合。下面分析这三种逻辑。

“与” 是正则表达式中最普遍的逻辑关系。一般来说,如果正则表达式中的元素没有任何量词(比如*、?、+)修饰,就是”与”关系。比如正则表达式:

表示同时出现a、b、c三个字符。

连续字符是“与”关系的最佳代表。此外,有些环视结构也可以表达“与”关系。比如顺序肯定环视(?=exp)表示自身出现的位置后面能匹配表达式exp,换而言之,就是在它后面必须出现表达式exp。例如:

\w+(?=ing)

表示单词的后面必须是ing结尾。
除了顺序肯定环视外,逆序肯定环视也能表达“与”关系。

比如匹配DIV标签里的内容,例如<div>logo</div>中的logo,就可用以下正则表达式来匹配:

(?<=div>).*(?=</div>)

(?<=div>) 表示自身(即要匹配的部分)出现的位置前面匹配表达式” <div> ” , (?=</div>) 表示它后面需要匹配的表达式” </div> “,中间的”.*”就是匹配到的内容。

“或”是正则表达式中容易出现的逻辑关系。
如果“或”代表元素可以出现,也可以不出现,或者出现的次数不确定,可以用量词来表示“或”关系。比如以下表达式表示在此处,字符a可以出现,也可以不出现:

以下表达式表示在此处,字符串ab必然要出现1次,也可以出现无限多次:

(ab)+

如果“或”表示出现的是某个元素的一个,那么可以使用字符组。比如以下正则表达式表示此处出现的字符是a、b、c中的任何一个:

[abc]

如果要匹配多个字符,则使用分支结构(……|……)。比如匹配单词foot及其复数形式,就可以用正则表达式:

f(oo|ee)t

或者使用如下形式

f[oe]{2}t

提到”非”,最容易想到正则表达式中的反义和”^”元字符。比如 \d 表示数字,那么其对应的 \D 就表示非数字; [a] 表示a字符,那么 [^a] 就表示这个字符不是a。

“非”关系最常用来匹配成对的标签,例如双引号字符串的匹配,首位两个双引号很容易匹配,其中的内容肯定不是双引号(暂不考虑转义的情况),所以用 [^"] 表示,其长度不确定,用*来限定,所以整个表达式如下:

[^"]*

比如,需要匹配HTML里成对的A标签,先匹配左尖括号,紧接着是a字符,后面可以是任意内容,最后是一个右尖括号。在这对括号之间可以出现空格、字母、数字、引号等字符,但是不能出现“>”字符,于是就可以用排除型字符组“[^>]”来表示。再加上后面的配对标签,整个表达式如下:

<a[^>]*>.*<\/a>

运行下面这段代码验证这个表达式:

$reg = "#<a[^>]*>(.*)<\/a>#" ; $str = '<a href="http://baidu.com">baidu</a>---<a href="http://sohu.com">sohu</a>' ; preg_match_all( $reg , $str , $m ); print_r( $m );

运行结果:

Array
    [0] => Array
            [0] => <a href="http://baidu.com">baidu</a>---<a href="http://sohu.com">sohu</a>
    [1] => Array
            [0] => baidu</a>---<a href="http://sohu.com">sohu

发现结果不符合预期,出现了嵌套匹配。原因在于A标签之间的文本忘了做排除型匹配,于是修改后的正则表达式就成了<a[^>]*>([^<>]*)<\/a>。经过修改后就符合预期了。

$reg = "#<a[^>]*>([^<>]*)<\/a>#"; $str = '<a href="http://baidu.com">baidu</a>---<a href="http://sohu.com">sohu</a>'; preg_match_all($reg, $str, $m); print_r($m);

运行结果为:

Array
    [0] => Array
            [0] => <a href="http://baidu.com">baidu</a>
            [1] => <a href="http://sohu.com">sohu</a>
    [1] => Array
            [0] => baidu
            [1] => sohu

注:上述例子也可以使用前一篇博文中讲过的懒惰匹配。修改正则如下:

<a[^>]*>(.*?)<\/a>

除了反义和排除型字符组外,否定环视也能表示“非”这种关系。比如有一串文字:“ab<p>onecde<div>fgh</div><img src=”“>”。现在需要匹配除P标签外的所有标签。换而言之,就是先匹配所有HTML标签,可以使用如下表达式:

</?\b[^>]+>

匹配闭合的“<XXX>”或“</XXX>”标签,然后再排除“XXX”或“/XXX”部分是P的标签,于是使用顺序否定环视,用表达式:

(?!/?p\b)

排除了“<”或“</”这个位置后是P字符的情况,这样就满足需求了。最终的表达式则为:

<(?!/?p\b)[^>]+>

通过上面的分析得到正则表达式中的“与或非”关系及其代表语法,如表所示。

文章目录一 正则表达式匹配原理1.1 正则表达式1.2 DFA1.3 正则表达式和DFA的关系1.4 正则匹配过程二 DFA的构建三 DFA与正则的转化3.1 DFA转正则表达式3.2 正则表达式转DFA3.2.1 正则表达式转NFA3.2.2 NFA确定化四 js中的正则正则表达式匹配原理 1.1 正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。例如,筛选所有以包含连续
最近在写模糊搜索的时候,使用mangodb对数据库进行查询。需求是输入框中可以供用户输入多个搜索项,需要返回的字段满足这多个搜索项的内容。 刚开始摸不着头脑,一般用正则都是写的或的关系,最后还是在文档里找到了答案。 /(?=.*失败)(?=.*成功了)/ 类似上面的方法,每个()表示你所要放置的一个条件,该正则匹配的结果必须满足每一个括号中的内容。括号里的内容需要以?=开始,.*表示任意个其他字符。 其实很简单,这样以括号区分的话,就不要求先后顺序,只要共同包含这些字段即可
正则表达式(regular expression)是计算机科学中的一个概念,又称规则表达式,通常简写为regex、regexp、RE、regexps、regexes、regexen。 正则表达式是一种文本模式。正则表达式是强大、便捷、高效的文本处理工具。正则表达式本身,加上如同一门袖珍编程语言的通用模式表示法(general pattern notation),赋予使用者描述和分析文本的能力。配...
public static void main(String[] args) { String str = "abc|ass|sdf"; String[] temp = str.split("|");
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/voo00oov/article/details/46965705 今天使用正则表达式是遇到一个问题, 磨了半天, 发现犯了个低级错误, 因此记录下来加深印象 问题描述: 我需要把^drawable(-[a-zA-Z0-9]+)*$...
2. AB00CEACef3c 则对应的正则表达式为: QRegExp mac_in_regExp("(((([0-9A-Fa-f]{2})(-[0-9A-Fa-f]{2}){5}))|([0-9A-Fa-f]{12}))"); 以上例子在Qt中使用。