linux基础-正则表达式


0. 问题引入 
    字符串是计算机应用中最为广泛的处理对象之一
    如: http、代码 ==
    并且字符串的组合规则形式多样化,比如: 
        数字字符串 
        email地址字符串 112223355@qq.com
        IP地址字符串 172.110.0.1 
        
    这些都是我们程序设计需要处理的对象,现在的问题是: 
        计算机要处理这些字符串,首先要用某种语言(或
        表达式,数据类型等等)去描述这些字符串的规则。
    
    => 正则表达式 Regular Expression 
    
1. 正则表达式 
    是什么玩意儿呢? 
    正则表达式是用来描述某种规则字符串的表达式。
    脱离了具体语言的一些规则,但是现在大多数程序设计语言
    都实现了或者支持正则表达式; 
        如: 
            C/C++ 
            python 
            java 
            C# 
            ......
        但是每种语言中实现正则表达式的规则略有不同。
        
2. 正则表达式大的规则 
    正则表达式是描述某种规则字符串的表达式。
    如: 
        [0-9]+    
        十进制数字字符串 
    
    正则表达式也叫做 匹配模式(pattern),它是由一组特定含义的字符串组成,
    通常用于匹配和替换文件。
    
    在正则表达式中的字符,分为两种: 
        (1) 普通字符串 : 只代表自己本身含义的字符
        (2) 元字符 : 有特殊含义(不代表自己)的字符
    
    正则表达式中的元字符: 
        .    匹配任意单个字符
        
        []    字符组。虽然由多个字符构成,但它任然只匹配单个字符,
                而字符组能够匹配的单个字符都在[]内列举出来啦。 
                []仅仅匹配括号内的单个字符!!! 
                例子: 匹配一个能够组成十六进制数的字符
                    [0123456789abcdefABCDEF]
            注意: 
                []字符组内部有一个元字符 - 
                -在[]内用于链接ASCII连续的字符
                => [0-9a-fA-F] 
                
            例子: 
                描述一个可以作为C语言标识符的字符
                [0-9a-zA-Z_]
                
        [^]    排除字符组。匹配单个字符,匹配除[]内以外的所有单个字符
            如: 
                非十进制数字字符
                [^0-9]
                
        \d    digtial 
            匹配单个十进制数字字符 
            \d <=> [0-9]
            
        \D    Digtial 
            匹配单个非十进制数字字符 
            \D <=> [^0-9]
        
        \w    word 匹配单个单词中能出现的字符 
            匹配字母、数字、_ 
            \w <=> [a-zA-Z0-9_]
            
        \W    匹配单个非 字母、数字、_
            \W <=> [^a-zA-Z0-9_]
            
        \s    匹配单个空白符 
            \s <=> [\f\n\t\r\v] 
                \f 换页
                \n 换行 
                \r 回车 
                \t 制表 
                \v 垂直制表
        
        \S    匹配单个非空白符
            \S <=> [^\f\n\t\r\v] 
            
            例子: 如果是排除字符组,'^'需要放置前面
                [a-z^0-9] 
                匹配单个字符 a-z 0-9 ^
        -------------------------------------------
            
        匹配多个字符: 
            + 匹配一个或多个先前的字符(或模式)
                如: 
                    09+ 
                        => 
                            09
                            099
                            0999
                            09999
                            ....
                            099.....9
                    0[0-9]+
                        => 
                            0[0-9]
                            0[0-9][0-9]
                            0[0-9][0-9][0-9]
                            .......
                            0[0-9][0-9].....[0-9] 
                            
            * 匹配0个或多个先前字符(或模式)
                如: 
                    09* 
                        => 
                            0
                            09
                            099
                            0999
                            .....
                            0999....99
                    [0-9]*
                        => 
                            "" 空串
                            [0-9]
                            [0-9][0-9]
                            ......
                            [0-9][0-9]....[0-9]
                            
            ? 匹配0个或1个先前字符(或模式)
                如: 
                    09? 
                        => 
                            0
                            09 
                    [0-9]? 
                        => 
                            "" 空串 
                            0 
                            1 
                            2 
                            ...
                            9 
                            
            {数字} 匹配固定数目的字符(或模式)
                如: 
                    88[0-9]{3} 
                        <=> 88[0-9][0-9][0-9]
                    09{3}
                        <=> 0999
                        
            {最小数目, 最大数目}
                匹配至少 “最小数目”,到至多“最大数目”先前的字符(或模式)
                如: 
                    8{1,3}
                        => 
                            8
                            88
                            888
                            
            {最小数目, }
                匹配至少“最小数目”,上不封顶 的先前字符(或模式) 
                如: 
                    abc{1, } 
                        => 
                            abc
                            abcc 
                            ....
                            abccc..cc 
                            
            ()    作为一个整体,子模式 
                如: 
                    (abc){1,3}
                        => 
                            abc
                            abcabc
                            abcabcabc 
                            
            (|) 二选一 
                如:  
                    (abc|123){2} 
                        <=> (abc|123)(abc|123)
                            abcabc
                            abc123
                            123abc
                            123123
                    
    转义元字符: 
        \元字符  => 元字符就不是元字符,就是普通字符啦
        如: 
            \. 代表一个普通字符'.'
            \* 代表一个普通字符'*'
            \+ 代表一个普通字符'+'
            ......
 
3. 正则表达式的使用 
    grep(egrep) 用来在一个文件(ASCII,字符)中查找一个特定的字符串。
        egrep是用扩展的正则表达式去查找!   
        
        语法: 
            grep(egrep)  options [正则表达式] files 
            在files列出的所有文件里面,查找以“正则表达式”所描述的字符串。
            
            options : 
                -n 显示查找到的字符串所有行号
                -E 用扩展的正则表达式 
                    grep -E 
                        => 
                            egrep
                -i ignore在字符串查找时忽略大小写
                    -i "main"
                        [mM][aA][iI][nN] 
                
                -# 表示同时显示匹配行的上下#行 
                    #表示一个整数值
                -c count 打印每个文件里面匹配行的个数 
                    加-c不会显示文件匹配到的内容。
                -H 显示文件名 
                -h 不显示文件名 
                
                    匹配内容颜色高亮显示 
                --color=always 总是高亮显示 
                --color=never  不高亮显示 
                --color=auto   随意
                
            例子: 
                egrep -niH -1 "[0-9]+" ./*.sh --color=always
        
    -------------------------------------------------------
    find 用来在一个文件系统中查找指定的文件 
    
        语法: 
            find path options 
            path: 表示搜素路径,指定去文件系统的哪个位置去搜素
            options : 
                -name pattern 
                    指定要查找的文件的名字,可以用通配符
                    * 代表0个或多个任意字符 
                    ? 代表一个任意字符
                    如: 
                        find ./ -name "*.c"
                        在当前目录(以及当前目录下面的目录下面...)查找
                        所有的以.c结尾的文件。
                        
                -regex pattern 
                    以正则表达式的方式指定要查找的文件名 
                    注意: 路径也是正则表达式描述的内容
                    如: 
                        find ./ -regex ".*[ch]" 找所有以c结尾或者h结尾
                        find ./ -regex ".*\.c"  找所有以.c结尾的文件  
                        
                -type b|c|d|p|f|l|s 指定要搜素的文件的类型 
                    b: block块设备 
                    c: char 字符设备 
                    d: dir 目录 
                    p: pipe 管道 
                    f: regular file 普通文件 
                    l: link 符号链接 软连接 
                    s: socket 套接字 
                    如: 当前目录下找所有名字以.c结尾的符号链接文件
                        find ./ -name "*.c" -type l  
                        
                -size n[cwbKMG] 
                    -size 5    
                        5*512  默认为块
                    b: 单位为块  a block(512Bytes)
                    c: 单位为字节 
                    w: work 单位为字 for two-byte
                    K: 1KB = 1024 Bytes
                    M: 1MB = 1024 KB 
                    G: 1GB = 1024 MB 
                    如: 
                        find ./ -name "*.c" -size 2c
                        
                -perm mode 要查找的文件的权限 
                    permission 权限 
                    mode 有两种写法: 
                        -mode 要求所有 (为1)权限位都要被匹配 
                            如; 
                                -perm -664 
                                待查找的文件权限必须为 110 110 100
                        /mode 只要匹配一位即可 
                            如: 
                                -perm /111
                                带查找的文件权限只要有一个可执行的位即可
                                
                -newer file 
                    查找比文件file更新的文件 
                    带查找的文件的修改的时间在file这个文件的后面即可。
                    如: 
                        find ./ -newer 9.sh 
                        
                -delete 
                    找到即删除
                    如: 
                        find ./1.txt ./2.txt -delete
                        find ./xxx/ -delete 
                
                -exec command {} \; 
                    每查找到一个文件就执行 command 这个命令,
                    {} 代表找到的文件的文件名,找到一个文件,就执行一次command
                    这个命令。
                    如: 
                        find ./ -name "*.c" -exec ls -l {} \;
                        
                -exec command {} + 
                    所有文件查找完成后,再执行command这个命令,
                    {} + 代表所有查找到的文件的文件名(以空格隔开) 
                    
4. 标准C库,对正则表达式的支持 
    案列: 
        写一个C语言程序,判断一个字符串是否为IP字符串? 
        "abc192.168.31.111abcfdsdafh"
        void find_ip(const char * str)
        {
            
        }
        
    用正则表达式的语法来描述一个正确的IP字符串: 
        "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" 
        
    关于C库对正则表达式的支持的AIP函数: 
        NAME
            regcomp, regexec, regerror, regfree - POSIX regex functions

        SYNOPSIS
           #include <sys/types.h>
           #include <regex.h>
            
            regcomp : 用来编译正则表达式
                编译好的正则表达式用类型 regex_t 来描述。 
                "正则表达式"原始字符串 -> regex_t 编译好的正则表达式 
          1、 int regcomp(regex_t *preg, const char *regex, int cflags);
                @preg : 指向的地址空间,用来保存编译好的正则表达式
                @regex: 指向原始的待编译的正则表达式字符串 
                @cflags : 有如下标志,用位或实现 
                    REG_EXTENDED : 用扩展的正则表达式语法编译 
                    REG_ICASE : ignore case 忽略大小写 
                    REG_NOSUB : 不包含子模式 
                    .....
                    如: 
                        用扩展的语法,并且忽略大小写 
                        REG_EXTENDED | REG_ICASE
                返回值: 
                    成功返回0 
                    失败返回一个错误码,该错误码需要调用 regerror去解析!
                        
    ===================================================================================================                
            待查找的原始字符串: "abc192.168.31.111abcfdsdafh"    
            以正则表达式去找: "([0-9]{1,3})\\.[0-9]{1,3}\\.([0-9]{1,3})\\.([0-9]{1,3})"
            regexec: 用来匹配正则表达式所描述的模式
                模式: 
                    总模式 192.168.31.111
                        [3, 17)    
                
                    子模式 
                        192  [3, 6)
                        31   [11,13)
                        111  [14,17)
                匹配的结果用 regmatch_t 来描述,返回的是再木船中匹配到的模式对象
                    下标范围( [起始下标, 终点下标)   )
                    typedef struct 
                    {
                       regoff_t rm_so; //start offset 起始偏移量
                       regoff_t rm_eo; //end offset 终点偏移量 
                       
                       一个模式需要对应一个regmatch_t类型的结构体变量!
                            例子: 
                                regmatch_t t;
                                t.rm_so = 3;
                                t.rm_eo = 17;
                                [rm_so , rm_eo)
                     } regmatch_t;
                                
           2、int regexec(const regex_t *preg, const char *string, size_t nmatch,regmatch_t pmatch[], int eflags);
                @preg : 正则表达式的指针。
                @string : 原始的等待匹配的字符串。待查找的字符串
                @nmatch : 正则表达式中有多少个模式 
                        总模式(1个) + 子模式个数 
                @pmatch : 结构体数组
                    保存匹配到的模式的信息。
                    nmatch 其实就是结构体数组元素个数!
                    
                    总共有多少个模式需要匹配,则需要有多少个结构体regmatch_t
                @eflags: 标志是否匹配行首或行尾。 
                    一般为0  
                返回值: 
                    如果成功(匹配到了)返回0 
                    如果失败返回 REG_NOMATCH 
            
    =================================================================================================            
                       
            regerror: 把 regcomp/regexec 运行返回的错误码,转换成相应的错误
                字符串信息。
          3、size_t regerror(int errcode, const regex_t *preg, char *errbuf,size_t errbuf_size);
                @errcode : 错误码。由regcomp/regexec返回的值。
                @preg : 编译好的正则表达式 
                @errbuf : 指向一段内存,用来保存转换后的错误提示信息
                @errbuf_size : errbuf的大小。最多能够保存多少个字节信息
                返回值: 
                    返回填充到errbuf中的错误提示字符串的长度。 
                    
    ===================================================================================================        
            4、regfree:用来释放preg指向的空间的。
           void regfree(regex_t *preg);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值