浅谈Linux中的正则表达式和Makefile工程管理文件

注:以下内容均为作者个人见解,若有不正确的地方,还请读者斧正

同时如果对你帮助的话,还请点赞,收藏加关注,你们的支持是我最大的动力!


一、正则表达式

场景描述:比如你现在要写一个程序,其中有一个功能是匹配以一个日志文本中的IP地址。

IP地址:点分式的字符串

192.168.31.1

0.0.0.0

循环

        然后一个字符一个字符的比对

ip_str[0] >= '0'&&ip_str[0] <='9'

这样写就会逻辑很复杂。

正则表达式就是用来描述某种规则字符的表达式,主要用于模糊搜索(查询)

要查找IP地址可以按照规则搜索

分析IP地址的规则:

  • 一共分为四段
  • 每一段至少一个数字至多三个数字
  • 两端中间会有一个点

正则表达式里面字符串中字符分为两类:

  • 普通字符:只代表自己
    • 1 2 a b ...
  • 元字符:不代表自己,有特殊含义(这个含义优先)

    • . * ? + \ ...

注意:元字符想要表示自己本身原来的意思的话,需要用(\)反斜杠进行转义

1.正则表达式中元字符

  • . :表示匹配任意单个字符
    • 示例:

表达式:[123456789] 表示在1~9的字符范围内去匹配一个

可以匹配到:1 2 3 4 5 6 7 8 9

表达式:[13579abcd] 表示在13579abcd的字符范围内去匹配一个

可以匹配到:1 3 5 7 9 a b c d

字符组可以用 - 来表示一个范围

[0123456789] 可以写成 [0-9]

[abcdefghij] 可以写成 [a-j]

其实就是按照ASCII码去列举范围

  • \w :表示匹配字母、数字以及( _ 下划线)

    • 示例:

表达式:\w 表示在0~9、a-z、A-Z、_这些字符范围内去匹配一个

可以匹配到:0-9 a-z A-Z _

  • + :表示匹配一个或多个先前字符或者是模式 (贪婪匹配)
    • 示例:

表达式:\w+ 表示匹配一个或多个字母、数字、_

可以匹配到:1 11 1111 ....

         :12 12222 12315646

        ....

表达式:1+ 表示匹配一个或多个1

可以匹配到:1 11 111 1111 ....

表达式:ab+ 表示先匹配a再匹配一个或多个b

可以匹配到:ab abb abbb ...

  • * :表示匹配零个或多个先前字符或模式(惰性匹配)
    • 示例:

表达式:ab* 表示先匹配a再匹配零个或多个b

可以匹配到:a ab abb abbb ...

  • ? :表示匹配零个或一个先前字符或模式
    • 示例:        

表达式:ab?

可以匹配到:a ab

  • {数字} :表示匹配固定数目的先前字符或模式
  • 示例:

表达式:a{5} 表示完成匹配到5个a

可以匹配到:aaaaa

  • {min,} :表示至少匹配 min 个先前字符或模式
  • 示例:

表达式:a{5,} 表示至少匹配到5个a

可以匹配到:aaaaa aaaaaaaa aaaaaaaaa ....

  • {min,max} :表示至少匹配 min 个至多匹配 max 个先前字符或模式
    • 示例:

表达式:a{2,3} 表示至少匹配2个a,至多匹配3个a

可以匹配到:aa aaa

  • () :表示子模式,其内部表达式看成一个整体
    • 示例:

表达式:(12+)+ 表示至少一个或多个(12或12222... )

可以匹配到:12 122122 12221222....

分析IP地址的规则:

  • 一共分为四段
  • 每一段至少一个数字至多三个数字
  • 两段中间会有一个点

匹配IP地址的正则表达式:

192.168.31.1

0.0.0.0

// 先匹配点分式

\.\.\. # 表示匹配三个点

[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}

[0-9]{1,3}\.

[0-9]{1,3}\.

[0-9]{1,3}\.

[0-9]{1,3}

完全可以写成:([0-9]{1,3}\.){3}[0-9]{1,3}

优化匹配IP的正则表达式

ip最大:255.255.255.255 广播地址

[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} 这个存在问题

分析:

        [12]? 最高位要么是1要么是2要么有要么没有

        [0-9]{1,2} 至少一个最多两个

        [12]?[0-9]{1,2} 一段的

        [12]?[0-9]{1,2}\.[12]?[0-9]{1,2}\.[12]?[0-9]{1,2}\.[12]?[0-9]{1,2}

2.C/C++对于正则表达式的支持

C/C++标准库中,对于正则表达式有一定的支持

需求:

  •         写一个C++程序,来获取一个字符串中的点分式字符串。
  • char *GetIPV4Address(const char *src_str)
    {
    }
    /*
    比如:
        输入:adsajdalkdj192.168.31.1asdjalkdj
        输出:192.168.31.1
    */
    

    3.正则表达式的API接口

  • #include <regex.h>
    
    // 正则表达式的接口头文件
    int regcomp(regex_t *preg, const char *regex, int cflags);
    
    int regexec(const regex_t *preg, const char *string, size_t nmatch,regmatch_t
    pmatch[], int eflags);
    
    size_t regerror(int errcode, const regex_t *preg, char *errbuf,size_t
    errbuf_size);
    
    void regfree(regex_t *preg);

4.编译正则表达式

int regcomp(regex_t *preg, const char *regex, int cflags);

    功能:
        用来编译 "正则表达式" 的。编译完成的政协表达式用regex_t 类型表示
        "正则表达式"原始字符串(手写的正则表达式)编译完成之后 regex_t 类型
    @preg:
        regex_t *类型
        指向空间,就是用来保存编译后的正则表达式的。
    @regex:
        const char *类型
        指向空间是存储原始字符串(正则表达式)的。没有被编译过的正则表达式字符串
    @cflags:
        int 类型
        标志位:
            REG_EXTENDED 用来扩展正则表达式的语法
            REG_ICASE ignore case 忽略大小写
            REG_NOSUB 不包含子模式
            以上标志位都是可以通过|运算符进行结合的
    @return:
        返回值为0表示无错误。
        返回值不为0表示错误,该返回值为一个错误码,需要通过regerror去进行错误解析

5.进行正则表达式的匹配

int regexec(const regex_t *preg, const char *string, size_t nmatch,regmatch_t
pmatch[], int eflags);

    功能:
        用于匹配正则表达式所描述的模式
    @preg:
        正则表达式,匹配模式。(也就是编译好了正则表达式,一般由regcomp赋值)
    @string:
        const char *类型
        原始字符串(母串)。需要进行匹配的原始字符串
    @nmatch:
        size_t 类型
        提前告知有多少个模式,总模式=(1个)+子模式数量
    @pmatch:
        regmatch_t 类型数组
        描述匹配结果,返回的是再母串中匹配到的下标范围,其实下标~结束下标
        typedef struct
        {
            regoff_t rm_so; // rm_so : start offset 起始位置下标
            regoff_t rm_eo; // rm_eo : end offset 终止下标
        } regmatch_t;

        模式匹配信息数组
        数组大小为nmatch大小
            一个模式就需要有一个regmatch_t
            指定了多少模式就有多少个regematch_t
    @eflags:
        int 类型
        表示十分匹配行首或行尾,一般为0
    @return:
        返回值为0表示匹配到了数据
        返回值为REG_NOMATCH表示失败

6.错误解析

size_t regerror(int errcode, const regex_t *preg, char *errbuf,size_t
errbuf_size);

    功能:
        用来吧regcomp和regexec函数执行返回的错误进行解析的,转换为错误信息字符串的
    @errcode:
        int 类型
        错误码。也就是需要进行解析的错误码
    @preg:
        const regex_t *类型
        编译好的正则表达式
    @errbuf:
        char *类型
        指向的空间用于保存解析错误信息之后,存储错误信息字符串的
    @errbuf_size:
        size_t 类型
        表示errbuf大小
    @return:
        返回值为填充到errbuf中的错误提示信息的字符串长度

7.正则表达式清理

void regfree(regex_t *preg);
/*
    功能:
        是否preg指向的那个空间的
    @preg:
        就是编译后的正则表达式
*/

二、Makefile工程管理文件

Makefile 可以自动化编译工程文件

当我们执行 make 命令的时候,就会去找当前目录下对应的 Makefile 文件进行执行。

make :没有指定可执行文件名的时候,默认在当前路径下去找, Makefile 或是 makefile

make target :指定执行指令生成

1.Makefile文件的执行命令格式

  • 目标文件:依赖文件列表
    • 目标文件 :需要生成的文件(demo文件)(可执行文件/.o文件/库文件)
    • 依赖文件列表 :生成目标文件(demo文件)需要哪些文件才能生成(一般是.cpp文件)

注意: Makefile 中可以自己定义变量的,但是变量是没有类型,一般作为字符串使用

2.Makefile的变量的定义

语法: 变量名 赋值符号 值

  • 就地赋值:简单赋值
    • 变量名:=值
    • 示例: VALUE:="abcd"
  • 递归赋值:依赖于后面的变量来赋值,展开赋值
    • 变量名=值 #向后展开
    • 示例:
    • A=$(B)
      B:="123"
      
      //---
      A=$(B) ---> 需要执行到B:="123"
      

  • 追加赋值:在原有值的基础上,追加值进去 
    • 变量名+=值1 值2 值3 值4 ...
    • 示例: A+= "123" "456" "789"
  • 条件赋值:当符合条件的时候才会进行赋值
    • 变量名?=值 #当变量没有被定义或者没有被赋值的时候,才会进行复制
    • 示例: A?="123"

3.变量的使用

语法: $(变量名)

示例:

  • VALUE = 10 创建变量 VALUE
  • $(VALUE) 引用变量 VALUE 的值

4.自动变量

  • $* :不包含扩展名的目标文件名字
  • $@ :目标文件的完整名称
  • $+ :所有依赖文件名,以空格分开,可能会包含重复的依赖文件
  • $^ :所有依赖文件名,以空格分开,不包含重复文件
  • $< :第一个依赖文件名
  • $? :所有比目标文件晚的依赖文件,以空格分开

5.Makefile的函数

  • willdcard :文件名展开函数
    • 只能带一种参数,就是提供文件名的通配方式
    • 示例: SRC+=$(wildcard *.cpp) :表示把当前目录下的所有 .cpp 的文件全部获取到 SRC 这个变量里面
      • 注意:目录是相对 Makefile 而言,而不是针对终端而言
      • 而且不会包括子目录
  • patsubst :字符串替换函数
    • 带三个参数,分别为:
      • 原有格式,替换格式,需要替换的字符串
    • 示例: OBJ+=$(patsubst %.sh,%.cpp,$(SRC))
      • 将 SRC 变量中的文件名由 .sh 结尾改为 .cpp 结尾
      • 注意:并不会实际改变文件真正的名字,只是把 SRC 里面的值改变
      • % :通配符,只匹配 Makefile 文件中的字符串

注意:*是通配符任意字符。%通配符只能匹配Makefile文件中的任意字符。

注意:

  • Makefile文件用tab缩减来描述包含关系。
  • 指令要定格写
  • 规范:变量名一般都会使用大写
  • Makefile文件没有后缀(扩展名)
  • 可以开头大写,也可以小写,但是执行make的时候优先选择大写的Makefile文件
  • gcc在Makefile里面被定义成了cc变量
  • 所有的Makefile文件需要放在你要编译的工程目录下才能起效果。

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值