1 正则表达式介绍
用一个命令查找一个模式得到一类字符串时,这个模式应该包含以下信息:
-
字符类
:它们在模式中表示一个字符,取值范围是一类字符中的任意一个。
-
数量限定符:如IP地址的每一部分可以有1 –3个数字。
-
各种
字符类
以及
普通字符
之间的位置关系:如IP地址分四部分,用普通字符’.’隔开,
每部分
都可以用
字符类和数量限定符描述
。
规定
一些特殊语法表示字符类、数量限定符和位置关系,然后用这些特殊语法和普通字符一起表示一个模式,这就是
正则表达式
(Regular Expression)。
2 grep正则表达式的Extended规范
各种
工具和编程语言所使用的正则表达式规范的语法并不相同
,表达能力也各不相同,有的正则表达式规范引入很多扩展,能表达更复杂的模式,但各种正则表达式
规范
的基本概念都
是相通的
。grep所使用的正则表达式,它大致上符合POSIX正则表达式规范,此笔记学习、练习grep使用的正则表达式。
(1) 字符类
字符
|
含义
|
举例
|
.
|
匹配任意
一个字符
|
abc.可以匹配abcd、abc9等
|
[]
|
匹配括号中的
任意一个字符
|
[abc]d可以匹配ad、bd或cd
|
-
|
在[]
括号内表示字符范围
|
[0-9a-fA-F]可以匹配一位十六进制数字
|
^
|
位于
[]括号内的开头
,匹配
除
括号中的字符之外的
任意一个字符
|
[^xy]匹配除xy之外的任一字符,因此[^xy]1可以匹配
a1、b1但不匹配x1、y1
|
[[:xxx:]]
|
grep工具
预定义
的一些
命名字符类
|
[[:
alpha
:]]匹配一个字母,
[[:
digit
:]]匹配一个数字
|
(2) 数量限定符
字符
|
含义
|
举例
|
?
|
紧跟在它前面的单元应匹配零次或一次
|
[0-9]?\.[0-9]匹配0.0、2.3、.5等,由于
.
在正则表达式中是一个
特殊字符
,所以需要用
\转义
一下,
取字面值
|
+
|
紧跟在它前面的单元应匹配一次或多次
|
[a-zA-Z0-9_.-]+@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+
匹配email地址
|
*
|
紧跟在它前面的单元应匹配零次或多次
|
[0-9][0-9]*匹配至少一位数字,等价于[0-9]+,
[a-zA-Z_]+[a-zA-Z_0-9]*匹配C语言的标识符
|
{N}
|
紧跟在它前面的单元应
精确匹配N次
|
[1-9][0-9]{2}匹配从100到999的整数
|
{N,}
|
紧跟在它前面的单元应
匹配至少N次
|
[1-9][0-9]{2,}匹配三位以上(含三位)的整数
|
{,M}
|
紧跟在它前面的单元应
匹配最多M次
|
[0-9]{,1}相当于[0-9]?
|
{N,M}
|
应匹配至少N次,最多M次
|
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}匹配IP地址
|
(3) 位置限定符
字符
|
含义
|
举例
|
^
|
匹配
行首
的位置
|
^Content匹配位于一行开头的Content
|
$
|
匹配行末的位置
|
;$匹配位于一行结尾的;号,^$匹配空行
|
\<
|
匹配
单词开头
的位置
|
\<th匹配... this,但不匹配ethernet、tenth
|
\>
|
匹配单词结尾的位置
|
p\>匹配leap ...,但不匹配
parent、sleepy
|
\b
|
匹配
单词开头或结尾
的位置
|
\b
at
\b
匹配... at ...,但不匹配cat、atexit、batch
|
\B
|
匹配
非单词开头
和
结尾
的位置
|
\Bat\B匹配battery,但不匹配... attend、hat...
|
(4) 其它特殊字符
字符
|
含义
|
举例
|
\
|
转义字符
,普通字符转义为特殊字符,特殊字符转义为普通字符
|
普通字符<写成\<表示单词开头的位置,特殊字符.写成\.以及\写成\\就当作普通字符来匹配
|
()
|
将正则表达式的一部分括起来
组成一个单元
,可以对整个单元使用数量限定符
|
([0-9]{1,3}\.){3}[0-9]{1,3}匹配IP地址
|
|
|
连接
两个
子表达式
,表示
或的关系
|
n(o|either)匹配no或neither
|
Basic规范也有这些语法,只是字符?+{}|()应解释为普通字符,要表示上述特殊含义则需要加\转义。如果用grep而不是egrep,并且不加-E参数,则应该遵照Basic规范来写正则表达式。
3 sed与正则表达式
(1) sed简介
sed意为流编辑器(Stream Editor),在
Shell脚本和Makefile中作为过滤器
使用非常普遍,也就是把前一个
程序的输出引入sed的输入
,经过一
系列编辑命令转换为另一种格式输出
。
sed命令
不会修改原文件
,只是经过sed命令后输出需要部分。
(2) sed涉及的正则表达式及编辑命令
sed
处理的文件
既可以由标准输入重定向得到,也可以当命令行参数传入,命令行参数可以一次传入多个文件,sed会依次处理。sed的
编辑命令
可以直接当命令行参数传入,也可以写成一个脚本文件然后用-f参数指定,编辑命令的格式为:
其中pattern是
正则表达式
,action是
编辑命令
。sed
一行一行读出待处理文件
,如果某一行与pattern匹配,则执行相应的action,如果一条命令没有pattern而只有action,这个action将作用于待处理文件的每一行。
sed常用编辑操作:
/pattern/
p
|
打印匹配pattern的行
|
/pattern/
d
|
删除匹配pattern的行
|
/pattern/
s
/pattern1/pattern2/
|
查找符合pattern的行,将该行第一个匹配pattern1的字符串替换为pattern2
|
/pattern/
s
/pattern1/pattern2/
g
|
查找符合pattern的行,将该行所有匹配
pattern1的字符串替换为pattern2
|
(3) sed命令行格式
根据(2)中对sed
处理的文件
和
编辑命令
的描述可得sed命令行的基本格式为:
sed option 'script' file1 file2 ...
sed option –f scriptfile file1 file2 …
|
-
option表示sed的可选参数,如要想只输出处理结果则option为-n。
-
‘script’表示脚本命令[ (2)中提到的编辑命令 ]。
-
filen表示要用sed处理的文件。
-
-f属option范畴,它允许将脚本命令编写成脚本文件再传给sed。
4 awk
(1) awk介绍
sed以行为单位处理文件,awk比sed强的地方在于不仅能以行为单位还能以列为单位处理文件。awk缺省的行分隔符是换行,缺省的列分隔符是连续的空格和Tab,但是行分隔符和列分隔符都可以自定义,比如/etc/passwd文件的每一行有若干个字段,字段之间以:分隔,就可以重新定义awk的列分隔符为:并以列为单位处理这个文件。
(2) awk命令行格式
awk基本用法和sed类似,awk命令行的基本形式为:
awk option 'script' file1 file2 ..
awk option -f scriptfile file1 file2 ...
|
和sed一样,awk处理的文件既可以由标准输入重定向得到,也可以当命令行参数传入,编辑命令可以直接当命令行参数传入,也可以用-f参数指定一个脚本文件,编辑命令的格式为:
/pattern/
{
actions
}
condition
{
actions
}
|
pattern是正则表达式,actions是一系列操作(编辑命令),awk程序一行一行读出待处理文件,如果某一行与pattern匹配,或者满足condition条件,则执行相应的actions,如果一条awk命令只有actions部分,则actions作用于待处理文件的每一行。
awk命令的condition部分还可以是两个特殊的condition-BEGIN和END,对于每个待处理文件,BEGIN后面的actions在处理整个文件之前执行一次,END后面的actions在整个文件处理完之后执行一次。
(3) awk内建变量
awk命令可以像C语言一样使用变量(但不需要定义变量)。就像Shell的环境变量一样,有些awk变量是预定义的有特殊含义的:
FILENAME
|
当前输入文件的文件名,该变量是只读的
|
NR
|
当前行的行号,该变量是只读的,R代表record
|
NF
|
当前行所拥有的列数,该变量是只读的,F代表field
|
OFS
|
输出格式的列分隔符,缺省是空格
|
FS
|
输入文件的列分融符,缺省是连续的空格和Tab
|
ORS
|
输出格式的行分隔符,缺省是换行符
|
RS
|
输入文件的行分隔符,缺省是换行符
|
awk还可以像C语言一样使用if/else、while、for控制结构。以前未“系统”掌握awk命令格式时做的笔记(例子):
shell awk读取文件中的指定行的指定字段
。
5 在C语言中使用的正则表达式
POSIX规定了正则表达式的C语言库函数:regex(3)。
man regex
。
用正则表达式匹配字符串是否为IP地址的C代码:
/*Filename: regex_in_c.c
*Brife: use c function to use regex
*Author: One fish
*Date: 2014.8.12 Tuesday
#include <sys/types.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
regex_t reg;
char regex[] = "[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}";
char str[] = "172.168.13.1";
size_t nmatch = 1;
regmatch_t pmatch[1];
char errbuf[100];
int i, re;
//Compile regex to reg
re = regcomp(®, regex, REG_EXTENDED | REG_NEWLINE);
if ( 0 != re ) {
regerror(re, ®, errbuf, 100);
printf("%s\n", errbuf);
exit(1);
//Use reg which compiled from pattern to match substring in whole string str
re = regexec(®, str, nmatch, pmatch, 0);
if (REG_NOMATCH == re) {
printf("No match\n");
exit(1);
} else if (0 == re) {
printf("matched:\n");
for (i = pmatch[0].rm_so; i < pmatch[0].rm_eo; ++i) {
putchar(str[i]);
printf("\n");
printf("%d, %d\n", pmatch[0].rm_so, pmatch[0].rm_eo);
//Free ® used in recomp
regfree(®);
return 0;
编译并执行程序:
gcc -o regex_in_c regex_in_c.c ./regex_in_c matched: 172.168.13.1 0,12 |
当在regcomp函数中的cflags参数中指定REG_NOSUB时nmatch和pmatch参数将会被忽略,不能再将它们的值输出来。
[2014.8.11-21.02 ---- 2014.8.12-16.29]
LCNote Over.
1 正则表达式介绍用一个命令查找一个模式得到一类字符串时,这个模式应该包含以下信息:l 字符类:它们在模式中表示一个字符,取值范围是一类字符中的任意一个。l 数量限定符:如IP地址的每一部分可以有1 –3个数字。l 各种字符类以及普通字符之间的位置关系:如IP地址分四部分,用普通字符’.’隔开,每部分都可以用字符类和数量限定符描述。规定一些特殊语法表示字符类、数量限定符和位
功能说明:查找文件里符合条件的字符串。
语 法:grep[-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>][-d<进行动作>][-e<范本样式>][-f<范本文件>][--help][范本样式][文件或目录...]
补充说明:grep指令...
匹配模式选择:
-E, --extended-regexp 扩展正则表达式egrep
-F, --fixed-strings 一个换行符分隔的字符串的集合fgrep
-G, -...
/* 1*/ "(standard input)",
/* 2*/ "cannot read bzip2 compressed file",
/* 3*/ "unknown %s option",
/* 4*/ "usage: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A num] [-B num] [-C[num]]\n",
/* 5*/ "\t[-e pattern] [-f file] [--binary-files=value] [--color=when]\n",
/* 6*/ "\t[--context[=num]] [--directories=action] [--label] [--line-buffered]\n",
/* 7*/ "\t[pattern] [file ...]\n",
/* 8*/ "Binary file %s matches\n",
/* 9*/ "%s (BSD grep) %s\n",
grep用法详解:grep与正则表达式
首先要记住的是: 正则表达式与通配符不一样,它们表示的含义并不相同!
正则表达式只是一种表示法,只要工具支持这种表示法,那么该工具就可以处理正则表达式的字符串。vi grep ,awk ,sed 等都支持正则表达式.
1基础正则表达式
grep 工具,以前介绍过。
grep -[acinv] '搜索内容串' filename
-a 以文本文件
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
输入awk的文本首先会被按“行”划分为很多条"记录",每一行表示一条记录,每一行再由分隔符划分成很多个“域”,分隔符默认是空格符,也可以通过命令参数-F来指定
比如 awk
sed -n ‘4,8p’ file #打印file中的4-8行
sed -n ‘4p’ file #打印file中的第4行
sed -n -e ‘8p;16p’ file > new # new文件的内容是 file中的第8、16行的内容提取
#-e命令行给出多个sed指令
1. 安装正则表达式工具
在Linux中,你可以使用grep、sed、awk等工具来进行正则表达式的操作。在大多数Linux发行版中,这些工具都已经默认安装,你可以通过以下命令来检查是否已经安装:
grep --version
sed --version
awk --version
如果未安装,则可以通过以下命令来安装:
sudo apt-get install grep
sudo apt-get install sed
sudo apt-get install awk
2. 准备练习文本
为了练习正则表达式,你需要准备一些文本样本。你可以使用在线文本生成器生成文本,或者复制一些已有的文本文件。
3. 练习正则表达式
使用终端命令行工具,你可以通过以下命令来练习正则表达式:
- grep:在文本文件中查找匹配指定模式的行。
grep 'pattern' filename
- sed:使用正则表达式在文本中进行替换。
sed 's/pattern/replacement/g' filename
- awk:使用正则表达式在文本中进行操作。
awk '/pattern/ {print $0}' filename
以上是三种常用的命令行工具。你可以使用它们来练习正则表达式,并根据需要使用其他工具。