当前位置: 首页 > news >正文

第二十天(正则表达式与功能实际运用)

在程序员一生的工作中,遇到的最多的数据就是字符串
字符串里面很有可能有很多的不需要的信息
我们需要从中间挑选出我们需要的
如果循环去写,比较简单的时候问题不大
规则多了,你的工作量会成倍上升的
为了解决这个问题 ---- 正则表达式

正则表达式 --- 一种规则,用于匹配我们需要的字符/字符串
简单一点就是一种匹配规则
字符串的处理通过这个正则表达式会变得简单很多

正则表达式字符分为两种
1 普通字符 -- 只代表这个字符本身
a b c d e f......
2 元字符:有特殊意义的字符
它不代表字符本身的意思,另外赋予它意思了
如:scanf printf里面的%

正则表达式里面的元字符
.   : 匹配任意的一个单个字符
[]  : 字符组,但是它只代表其中一个
[]里面可能会写很多个字符,但是只代表一个字符
只能有一个字符和[]里面的字符去匹配
挑里面有的去匹配
如:[abcdefg] -> 43720jklrhj423urlkehk23hijka
后面的字符串只有e 和 a才能被匹配
这个[]里面也有一个元字符 -
-:表示从ASCII码开始到ASCII码结束这一节所有的字符
有开始有结束才代表连接,否则就是-自己本身
[A-Z]: 表示 A到Z中间所有的字符,只会匹配其中一个
[a-z]: 匹配一个小写字母
[A-Za-z]:匹配
[0-9]:匹配数字字符
[-9]:这个没有开始,那么-就是它自己
匹配-或者9字符
^   : 排除字符,把它们排除掉
[^0-9] : 排除所有的数字字符,其它的字符都可以和我匹配
[^0-9A-Za-z] : 排除数字字符和字母

    字母  数字这些比较特殊,因此会有东西直接表示
\d  : 匹配数字字符
\D  : 排除数字字符
\w  : 匹配数字字母下划线
\W  : 排除数字字母下划线
\s  : 空白字符
\S  : 非空字符

匹配多个字符
+   : 匹配1个或者多个先前字符
[A-Z]+ 匹配长度至少为1的大写字母
[A-Z]
[A-Z][A-Z]
[A-Z][A-Z][A-Z]
[A-Z][A-Z][A-Z][A-Z]
........
dahsjkAbc  -> 只有A可以匹配
dhsajkDEf   -> DE可以匹配
dasdwqda    -> 没有
A
BC
DFG
.....

    *   :匹配0个或者多个先前字符
[A-Z]*
空的
[A-Z]
[A-Z][A-Z]
[A-Z][A-Z][A-Z]
[A-Z][A-Z][A-Z][A-Z]
........

    ?   : 匹配0个或者1个先前字符
[A-Z]?
空的
[A-Z]

    我们也可以指定数量来进行匹配
{数字}
a{3} 
aaa
[A-Z]{3}
[A-Z][A-Z][A-Z]
指定数量里面我们也可以给范围
{最小数量,最大数量}
[A-Z]{1,3}
[A-Z]
[A-Z][A-Z]
[A-Z][A-Z][A-Z]
如果没有最大数量表示上不封顶

    ()被看成是一个整体,这个整体我们叫子模式
(abc){1,3} 
abc
abcabc
abcabcabc
abc{1,3} -> 区分
abc
abcc
abccc
(|) 二选一
(abc|123){1,2}
abc
abcabc
abc123
123
123123
123abc
\ 转义字符
\.  ->普通的.
\d.c -> 1.c 11c 1cc 2cc 3dc
\d\.c -> 1.c 2.c 3.c
\\  ->普通的\
\*  ->普通的*

    ipv4 : 用4个字节表示一个ip地址
xxx.xxx.xxx.xxx
192.168.5.250   
有一个字符串待匹配
dhasjkdhwq3123.342432.123.34.53.6dashjk.123.234.12.4dhasjk
请你写一个正则表达式来匹配ip地址
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}

我在我的系统里面存了一个pxxxxx.c的这么一个文件,我忘记放哪里了,你帮我找一下
xxxxx是数字,我不记得有多少个了
p[0-9]+\.c

c语言支持了正则表达式

NAME
regcomp, regexec, regerror, regfree - POSIX regex functions

SYNOPSIS
#include <sys/types.h>
#include <regex.h>

       int regcomp(regex_t *preg, const char *regex, int cflags);
preg:编译好了的正则表达式 --- 就是它能看得懂的字节码
这个玩意儿是一个地址
regex:你编辑的正则表达式,是一个字符串
如:"p[0-9]+\.c"    
cflags: 标志 ,用位域实现的 
REG_EXTENDED    : 扩展的正则表达式,一般都带上这个标志
REG_ICASE       :  忽略大小写
REG_NOSUB       : 忽略子模式
REG_EXTENDED | REG_ICASE  用扩展的正则表达式并且忽略大小写
成功返回0,失败返回错误码


//运行我们的正则表达式
int regexec(const regex_t *preg, const char *string, size_t nmatch,
regmatch_t pmatch[], int eflags);
preg:编译好了的正则表达式
string:待匹配字符串
nmatch:你有多少个模式 1 + n,一般n <= 实际子模式数
总模式(1) + 子模式(n)
"ds(ajh)(kd)wh(jk)"
pmatch:匹配的信息,也就是匹配的结果
它是一个数组
pmatch = malloc(sizeof(regmatch_t) * nmatch) 
第一个元素为总模式
后面的为子模式
typedef struct {
regoff_t rm_so;//start 开始  待匹配字符串的下标
regoff_t rm_eo;//end   结束  待匹配字符串的下标
} regmatch_t;
eflags:一个标志
一般给0
返回值:
成功返回0,你可能会有后续继续的匹配
失败返回  REG_NOMATCH

       size_t regerror(int errcode, const regex_t *preg, char *errbuf,
size_t errbuf_size);
errcode:错误码
preg:编译了的正则表达式
errbuf:存放解析好了的错误信息
errbuf_size:你给errbuf的最大存储空间
成功返回实际写入errbuf里面的字节数

       void regfree(regex_t *preg);
释放preg


//心中有的数 如果是正则表达式是有问题的为1 如果是其它的表示为2 成功是0

int regerror(int errcode, const regex_t *preg, char *errbuf,
size_t errbuf_size)
{
int len = 0;
switch(errcode)
{
case 0:
len = strlen("success") < errbuf_size ? strlen("success") : errbuf_size;
strncpy(errbuf,"success",len);
return len;
case 1:
len = strlen("zheng ze biao da shi you wen ti") < errbuf_size ? strlen("zheng ze biao da shi you wen ti") : errbuf_size;
strncpy(errbuf,"heng ze biao da shi you wen ti",len);
return len;
case 2:
len = strlen("other") < errbuf_size ? strlen("other") : errbuf_size;
strncpy(errbuf,"other",len);
return len;
default:
return -1;
}


}    

#include <sys/types.h>
#include <regex.h>
#include <stdio.h>
#include <string.h>//我们挑网址出来  (www){1}\.[A-Za-z0-9]+\.(com){1}
#define REGEXSTRING "(www){1}\\.[A-Za-z0-9]+\\.(com){1}"const char * const str = "dsahejkdwqhdsaww.sadhjkdhwww.dashjd.www.baidu.com\
dashjkdhwqjww.baidu.cmwww.hehe.comasdwqwww.123123.comshadjkwqhk";int main()
{//编译我们的正则表达式//regex_t * preg = (regex_t *)malloc(sizeof(regex_t));//空间是在堆上面开的  搞完要释放的regex_t  preg;//在栈上面开的  代码块弄完自动释放int r = regcomp(&preg,REGEXSTRING,REG_EXTENDED);char buf[1024] = {0};if(r != 0)//错了{//解析错误信息 int l = regerror(r,&preg,buf,1023);if(l > 0)//解析错误成功{//最好补个\0buf[l] = 0;printf("regcomp error:%s\n",buf);return -1;}printf("不知道什么错误\n");return -2;         }//执行正则表达式//返回值如果为0  说明后面还有可能有未匹配到的const char * ptr = str;regmatch_t pmatch[3];//存放我们的结果while(1){r = regexec(&preg,ptr,3,pmatch,0);if(r != 0){break;}//匹配成功for(int i = 0;i < 3;i++){printf("[%ld,%ld) -> ",pmatch[i].rm_so + ptr - str,pmatch[i].rm_eo + ptr - str);strncpy(buf,ptr + pmatch[i].rm_so,pmatch[i].rm_eo - pmatch[i].rm_so);buf[pmatch[i].rm_eo - pmatch[i].rm_so] = 0;//补\0if(i == 0){printf("总模式:%s\n",buf);}else{printf("子模式:%s\n",buf);}}ptr += pmatch[0].rm_eo;//将匹配过的字符串给跳过}regfree(&preg);return 0;
}


//有用正则表达式的命令

find -> 查找
find [path] [options]
path:你要查找的路径
不给默认当前路径

    options:
-name -> 指定你要查找的名字
里面有两个通配符可以使用
* -> 所有的
? -> 一个字符
find ./ -name "*.c" -> 在当前路径下面查找所有的.c文件

-regex -> 用正则表达式来查

    查当前文件夹下面所有的数字.c文件
find ./ -regex "\d+\.c"

    -type 指定要查找的文件的类型
b      block (buffered) special 块设备

              c      character (unbuffered) special 字符设备
d      directory  文件夹
p      named pipe (FIFO) 有名管道
f      regular file 普通文件

              l      symbolic link; this is never true if the -L option or the
-follow  option is in effect, unless the symbolic link is
broken.  If you want to search for symbolic links when -L
is in effect, use -xtype.
s      socket

              D      door (Solaris)

    -size 指定大小
默认以块为单位
-size 5
实际查找文件大小为 5 * 512字节

              `b'    for 512-byte blocks (this is the default if no suffix  is
used)  块

              `c'    for bytes 字节

              `w'    for two-byte words 两个字节

              `k'    for Kibibytes (KiB, units of 1024 bytes)

              `M'    for Mebibytes (MiB, units of 1024 * 1024 = 1048576 bytes)

              `G'    for  Gibibytes  (GiB,  units  of  1024  *  1024  * 1024 =
1073741824 bytes)

    -delete 找到及删除

    -exec commod {} \;
找到及执行 commod 
{}为执行结果的占位符
find ./ -name "*.h" -exec tar -jcvf 1.tar.bz2 {} \; 
找到当前路径下面所有的.h文件,然后将其压缩为 1.tar.bz2

grep:在一个文件里面查找对应的字符串
grep [OPTIONS] PATTERN [FILE...]
FILE你的待匹配的文件路径名
PATTERN : 正则表达式

        OPTIONS:
-n 显示查找到的字符串所在行
-E  用扩展的正则表达式

            -i 忽略大小写

            -# 同时显示匹配的上下#行


-c 打印每个文件匹配行的个数

-H 显示文件名

            -h 不显示文件名

http://www.dtcms.com/a/297755.html

相关文章:

  • VUE 学习笔记6 vue数据监测原理
  • 设计模式十:单件模式 (Singleton Pattern)
  • 空间信息与数字技术专业能从事什么工作?
  • 【LeetCode数据结构】二叉树的应用(二)——二叉树的前序遍历问题、二叉树的中序遍历问题、二叉树的后序遍历问题详解
  • uniapp创建vue3+ts+pinia+sass项目
  • 2025年RISC-V中国峰会 主要内容
  • 绘图库 Matplotlib Search
  • RISC-V VP、Gem5、Spike
  • 恋爱时间倒计时网页设计与实现方案
  • 借助Aspose.HTML控件,在 Python 中将 SVG 转换为 PDF
  • Vue nextTick
  • 基于超176k铭文数据,谷歌DeepMind发布Aeneas,首次实现古罗马铭文的任意长度修复
  • MySQL存储引擎深度解析与实战指南
  • Java面试题及详细答案120道之(001-020)
  • JAVA_FIFTEEN_异常
  • LeetCode 233:数字 1 的个数
  • Zero-Shot TrackingT0:对象分割+运动感知记——当“切万物”武士学会运动记忆,目标跟踪稳如老狗
  • 力扣面试150题--寻找旋转排序数组中的最小值
  • 互联网金融项目实战(大数据Hadoop hive)
  • 代码随想录算法训练营第五十三天|图论part4
  • Hive【Hive架构及工作原理】
  • Hive-vscode-snippets
  • 微信小程序文件下载与预览功能实现详解
  • nacos安装
  • SpringBoot配置多数据源多数据库
  • Androidstudio 上传当前module 或本地jar包到maven服务器。
  • 线性代数 上
  • Java 大视界 -- 基于 Java 的大数据分布式存储在工业互联网数据管理与边缘计算协同中的创新实践(364)
  • 从入门到进阶:JavaScript 学习之路与实战技巧
  • Nginx 安装与 HTTPS 配置指南:使用 OpenSSL 搭建安全 Web 服务器