美文网首页程序员
正则表达式学习笔记(一)基础知识

正则表达式学习笔记(一)基础知识

作者: wudanyang | 来源:发表于2017-09-01 14:49 被阅读16次

    一、什么是正则表达式?

    正则表达式就是用某种模式去匹配一类字符串的一种公式。


    二、正则表达式的组成

    在php中,正则表达式由三部分组成:分隔符、表达式和修饰符。

    • 分隔符:一般用:正斜线(/)、#、~或者%。
    • 表达式:由可以表示其他字符串的字符组成
    • 修饰符:可以开启或关闭某种功能(忽略大小写、多行匹配等)

    1.实例

    preg_match_all('%.*reg$%mi', $str, $arr);
    上面是一个php的正则表达式,参数为:

    1. 正则表达式
    2. 待匹配字符串
    3. 匹配到的字符串

    三、测试工具

    写出正则表达式就需要测试,测试工具很重要。一般来说,用在线正则匹配工具就可以满足要求,或者使用语言自带的正则函数。


    四、元字符

    26个字符可以组成任何单词。而元字符,可以通过组合去匹配到任何能见到的字符串。

    元字符 描述
    . 匹配除换行符以外的任意字符
    \w 匹配字母、数字、下划线或者汉字
    \s 匹配任意空白符
    \d 匹配数字
    \b 定界符:匹配单词开始或者结束
    ^ 匹配字符串开始
    $ 匹配字符串结束
    - 表示范围
    [] 匹配括号中任一字符
    * 量词:表示任意多个
    + 量词:一个或者多个
    ? 量词:一个或者没有
    {} 量词:在括号范围之内
    \W 匹配任意不是字母、数字、下划线或者汉字的字符
    \S 匹配非空白的字符
    \D 匹配非数字
    \B 匹配非单词开始或者结束

    五、匹配规则

    1.字符组

    [aeiou] 匹配括号中的任何一个字母

    c[aou]t 匹配 cat/cot/cut 而不能匹配caout

    [] 匹配单个字符

    2.转义

    元字符表示特殊的含义,如果想匹配元字符就需要用到转义。转义需要在需转义的字符钱加反斜线(\)。

    (.)表示任意字符,而(.)则表示 . 这个字符
    (\w)表示word、而(\w)则表示 \w 这个字符串

    3.分支

    分支就相当于编程时遇到了if语句。

    [ch]at 可以匹配 cat/hat
    (c|h|f|to)at 可以匹配 cat/hat/fat/toat

    在匹配时、就相当于遇到了选择语句,需要判断之后再匹配
    分支检测为if/else语句,遇到if中条件为真则不会继续匹配

    4.分组

    分组的作用就是将多个字符看做是一个整体。
    .* 表示任意字符重复任意次
    (abc)* 表示abc这个字符串以相同的顺序重复任意多次
    <table class="table table-bordered table-striped table-condensed">
    <tr>
    <td>类别</td>
    <td>语法</td>
    <td>描述</td>
    </tr>
    <tr>
    <td rowspan=3 align='center'>捕获</td>
    <td>(exp)</td>
    <td>匹配exp,并捕获文本到自动命名的组里</td>
    </tr>
    <tr>
    <td>(?《name》exp)</td>
    <td>匹配exp,并给匹配到的文本命名,也可以写成(?'name'exp)</td>
    </tr>
    <tr>
    <td>(?:exp)</td>
    <td>匹配exp并且不给此分组分配组号</td>
    </tr>
    <tr>
    <td rowspan=4 align='center'>零宽断言</td>
    <td>(?=exp)</td>
    <td>匹配exp前面的位置</td>
    </tr>
    <tr>
    <td>(?《=exp)</td>
    <td>匹配exp后面的位置(英文小于号无法显示,用书名号代替)</td>
    </tr>
    <tr>
    <td>(?!exp)</td>
    <td>匹配后面跟的不是exp的位置</td>
    </tr>
    <tr>
    <td>(?《!exp)</td>
    <td>匹配前面不是exp的位置(英文小于号无法显示,用书名号代替)</td>
    </tr>
    <tr>
    <td>注释</td>
    <td>(?#comment)</td>
    <td>提供注释,不对表达式产生影响</td>
    </tr>
    </table>

    5.反向引用

    \b(\w+)\b\s+\1\b
    

    这个可以匹配 go go 或者 a a
    \1 指的是在前面第一个捕获的分组

    也可以使用这个 \k< Word >

    \b(?< Word >\w+)\b\s+\k < Word > \b
    

    6.环视

    正则匹配有四种环视方式:

    • 顺序肯定环视(零宽度正预测先行断言)
    • 逆序肯定环视(零宽度正回顾后发断言)
    • 顺序否定环视(零宽度负预测先行断言)
    • 逆序否定环视(零宽度负回顾后发断言)

    四种方式对应的表达式分别为:

    • (?=exp)
    • (?<=exp)
    • (?!exp)
    • (?<!exp)

    乍一看确实很难理解,但是我这里有更好的理解方式:

    • 零宽度代表,匹配的时候只匹配位置,而不将匹配到的内容放到结果中
    • 正预测和正回顾则代表着,匹配到的位置存在是对的
    • 负预测和负回顾则代表着,匹配到的位置不存在才是对的(非)
    • 先行断言就像是你在预测一件事情,预测后面发生的就是这样的(在表达式后面发生)
    • 后发断言就像是事情已经发生了,然后才说出来这件事情(在表达式前面发生)

    理解了以上几条之后,你就可以开始写复杂的正则表达式了。

    例子:

    (?<![a-z])\d{7} 前面不是小写字母的7位数字

    7.贪婪、懒惰匹配

    .* 表示贪婪匹配,能匹配更多就匹配多个
    .*? 表示懒惰匹配,在能匹配更多个的时候优先不匹配

    懒惰限定符 描述
    *? 重复任意次,但尽可能少重复
    +? 重复1次或更多次,但尽可能少重复
    ?? 重复0次或1次,但尽可能少重复
    {n,m}? 重复n到m次,但尽可能少重复
    {n,}? 重复n次以上,但尽可能少重复

    六、模式

    1.忽略大小写(i)

    一般忽略大小写时为全局生效,若想部分生效需要如此:

    #ab(?i)c#
    

    此表达式会匹配abc和abC

    2.多行模式(m)

    <?php
    // 多行模式的本质是检查是否有 \n 换行符
    $source1 = 'abc\nabcd';
    $source2 = "abc\nabcd";
    if (preg_match_all('%^abc%m', $source1, $arr)) {
        echo "匹配成功--";
        var_dump($arr);
    } else {
        echo "匹配不成功--";
    }
    
    if (preg_match_all('%^abc%m', $source2, $arr)) {
        echo "匹配成功--";
        var_dump($arr);
    } else {
        echo "匹配不成功";
    }
    

    3.点号通配模式

    点号通配模式的作用是使正则表达式的点号元字符能匹配换行符,如果没有这个修饰符,点号不匹配换行符。

    // 点号通配模式(s),使点号可以匹配换行符
    $str = "<body><div class='content'>
    <div class='head'></div>
    <div class='body'></div>
    <div class='foot'></div>
    </div></body>";
    $arr1 = $arr2 = array();
    preg_match_all('%<body>(.*)<\/body>%', $str, $arr1);
    var_dump($arr1); // 为空
    preg_match_all('%<body>(.*)<\/body>%s', $str, $arr2);
    var_dump($arr2); // 匹配成功
    

    4.懒惰模式(U)

    加上懒惰模式,相当于在.*后面加上问号。

    5.结尾限制(D)

    加上结尾限制,则结尾不能有换行符

    6.支持UTF-8转义表达(u)

    启用u模式,模式字符串被当成utf-8。php4.1可用。

    // 支持 UTF-8 转义表达 (u)
    $str = "php 编程";
    if (preg_match("/^[\x{4e00}-\x{9fa5}]+$/u", $str)) {
        echo "该字符串都是中文";
    } else {
        echo "该字符串不全是中文";
    }
    

    七、实例

    1.匹配email

    \w{3,16}@\w{1,64}\.\w{2,5}
    

    2.匹配手机号码

    1\d{10}
    

    3.将UBB标签解析成HTML

    <?php 
    $str = '[url]1.gif[/url][url]2.gif[/url][url]3.gif[/url]';
    $reg = "#\[url\](.*?)\[\/url\]#"; // 此处使用懒惰模式匹配,否则会一直匹配到最后的标签
    $s = preg_replace($reg, "![](http://image.baidu.com/$1)", $str);
    
    echo $s;
    

    八、其他

    1.与:

    • abc
    • 肯定环视

    2.或:

    • a?
    • 字符组

    3.非:

    • ^a
    • \D \W \B
    • 否定环视

    4.优先级

    从大到小

    1. 转义符 \
    2. 括号和中括号
    3. 量词限定符 */+/?等
    4. 定位点和序列 ^/$/ 元字符、连字符
    5. 替换 |

    相关文章

      网友评论

        本文标题:正则表达式学习笔记(一)基础知识

        本文链接:https://www.haomeiwen.com/subject/pkfkjxtx.html