grep正则表达式规范 在sed、awk及C语言中用正则表达式

前端之家收集整理的这篇文章主要介绍了grep正则表达式规范 在sed、awk及C语言中用正则表达式前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1 正则表达式介绍

用一个命令查找一个模式得到一类字符串时,这个模式应该包含以下信息:@H_403_7@

  • 字符类:它们在模式中表示一个字符,取值范围是一类字符中的任意一个。
  • 数量限定符:如IP地址的每一部分可以有1 –3个数字。
  • 各种字符类以及普通字符之间的位置关系:如IP地址分四部分,用普通字符’.’隔开,每部分都可以用字符类和数量限定符描述

规定一些特殊语法表示字符类、数量限定符和位置关系,然后用这些特殊语法和普通字符一起表示一个模式,这就是正则表达式(Regular Expression)。@H_403_7@


@H_403_7@

2 grep正则表达式的Extended规范

各种工具和编程语言所使用的正则表达式规范的语法并不相同,表达能力也各不相同,有的正则表达式规范引入很多扩展,能表达更复杂的模式,但各种正则表达式规范的基本概念都是相通的。grep所使用的正则表达式,它大致上符合POSIX正则表达式规范,此笔记学习、练习grep使用的正则表达式。@H_403_7@


@H_403_7@

@H_403_7@

(1) 字符类

字符@H_403_7@

含义@H_403_7@

举例@H_403_7@

.@H_403_7@

匹配任意一个字符@H_403_7@

abc.可以匹配abcd、abc9等@H_403_7@

[]@H_403_7@

匹配括号中的任意一个字符@H_403_7@

[abc]d可以匹配ad、bd或cd@H_403_7@

-@H_403_7@

在[]括号内表示字符范围@H_403_7@

[0-9a-fA-F]可以匹配一位十六进制数字@H_403_7@

^@H_403_7@

位于[]括号内的开头,匹配括号中的字符之外的任意一个字符@H_403_7@

[^xy]匹配除xy之外的任一字符,因此[^xy]1可以匹配@H_403_7@

a1、b1但不匹配x1、y1@H_403_7@

[[:xxx:]]@H_403_7@

grep工具预定义的一些命名字符类@H_403_7@

[[:alpha:]]匹配一个字母,@H_403_7@

[[:digit:]]匹配一个数字@H_403_7@


@H_403_7@

(2) 数量限定符

字符@H_403_7@

含义@H_403_7@

举例@H_403_7@

@H_403_7@

紧跟在它前面的单元应匹配零次或一次@H_403_7@

[0-9]?\.[0-9]匹配0.0、2.3、.5等,由于.在正则表达式中是一个特殊字符,所以需要用\转义一下,取字面值@H_403_7@

+@H_403_7@

紧跟在它前面的单元应匹配一次或多次@H_403_7@

[a-zA-Z0-9_.-]+@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+匹配email地址@H_403_7@

*@H_403_7@

紧跟在它前面的单元应匹配零次或多次@H_403_7@

[0-9][0-9]*匹配至少一位数字,等价于[0-9]+,[a-zA-Z_]+[a-zA-Z_0-9]*匹配C语言的标识符@H_403_7@

{N}@H_403_7@

紧跟在它前面的单元应精确匹配N次@H_403_7@

[1-9][0-9]{2}匹配从100到999的整数@H_403_7@

{N,}@H_403_7@

紧跟在它前面的单元应匹配至少N次@H_403_7@

[1-9][0-9]{2,}匹配三位以上(含三位)的整数@H_403_7@

{,M}@H_403_7@

紧跟在它前面的单元应匹配最多M次@H_403_7@

[0-9]{,1}相当于[0-9]?@H_403_7@

{N,M}@H_403_7@

应匹配至少N次,最多M次@H_403_7@

[0-9]{1,3}\.[0-9]{1,3}匹配IP地址@H_403_7@


@H_403_7@

(3) 位置限定符

字符@H_403_7@

含义@H_403_7@

举例@H_403_7@

^@H_403_7@

匹配行首的位置@H_403_7@

^Content匹配位于一行开头的Content@H_403_7@

$@H_403_7@

匹配行末的位置@H_403_7@

;$匹配位于一行结尾的;号,^$匹配空行@H_403_7@

\<@H_403_7@

匹配单词开头的位置@H_403_7@

\<th匹配... this,但不匹配ethernet、tenth@H_403_7@

\>@H_403_7@

匹配单词结尾的位置@H_403_7@

p\>匹配leap ...,但不匹配parent、sleepy@H_403_7@

\b@H_403_7@

匹配单词开头或结尾的位置@H_403_7@

\bat\b匹配... at ...,但不匹配cat、atexit、batch@H_403_7@

\B@H_403_7@

匹配非单词开头结尾的位置@H_403_7@

\Bat\B匹配battery,但不匹配... attend、hat...@H_403_7@


@H_403_7@

(4) 其它特殊字符

字符@H_403_7@

含义@H_403_7@

举例@H_403_7@

\@H_403_7@

转义字符,普通字符转义为特殊字符,特殊字符转义为普通字符@H_403_7@

普通字符<写成\<表示单词开头的位置,特殊字符.写成\.以及\写成\\就当作普通字符来匹配@H_403_7@

()@H_403_7@

将正则表达式的一部分括起来组成一个单元,可以对整个单元使用数量限定符@H_403_7@

([0-9]{1,3}\.){3}[0-9]{1,3}匹配IP地址@H_403_7@

|@H_403_7@

连接两个子表达式,表示或的关系@H_403_7@

n(o|either)匹配no或neither@H_403_7@

Basic规范也有这些语法,只是字符?+{}|()应解释为普通字符,要表示上述特殊含义则需要加\转义。如果用grep而不是egrep,并且不加-E参数,则应该遵照Basic规范来写正则表达式。@H_403_7@

@H_403_7@

3 sed与正则表达式

(1) sed简介

sed意为流编辑器(Stream Editor),在Shell脚本和Makefile中作为过滤器使用非常普遍,也就是把前一个程序的输出引入sed的输入,经过一系列编辑命令转换为另一种格式输出。@H_403_7@


@H_403_7@

sed命令不会修改文件,只是经过sed命令后输出需要部分。@H_403_7@


@H_403_7@

(2) sed涉及的正则表达式及编辑命令

sed处理的文件既可以由标准输入重定向得到,也可以当命令行参数传入,命令行参数可以一次传入多个文件,sed会依次处理。sed的编辑命令可以直接当命令行参数传入,也可以写成一个脚本文件然后用-f参数指定,编辑命令的格式为:@H_403_7@

/pattern/action@H_403_7@

其中pattern是正则表达式,action是编辑命令。sed一行一行读出待处理文件,如果某一行与pattern匹配,则执行相应的action,如果一条命令没有pattern而只有action,这个action将作用于待处理文件的每一行。@H_403_7@


@H_403_7@

sed常用编辑操作:@H_403_7@

/pattern/p@H_403_7@

打印匹配pattern的行@H_403_7@

/pattern/d@H_403_7@

删除匹配pattern的行@H_403_7@

/pattern/s/pattern1/pattern2/@H_403_7@

查找符合pattern的行,将该行第一个匹配pattern1的字符串替换为pattern2@H_403_7@

/pattern/s/pattern1/pattern2/g@H_403_7@

查找符合pattern的行,将该行所有匹配@H_403_7@

pattern1的字符串替换为pattern2@H_403_7@


@H_403_7@

(3) sed命令行格式

根据(2)中对sed处理的文件编辑命令的描述可得sed命令行的基本格式为:@H_403_7@

sed option 'script' file1 file2 ...@H_403_7@

sed option –f scriptfile file1 file2 …@H_403_7@

  • option表示sed的可选参数,如要想只输出处理结果则option为-n。
  • ‘script’表示脚本命令[ (2)中提到的编辑命令 ]。
  • filen表示要用sed处理的文件
  • -f属option范畴,它允许将脚本命令编写成脚本文件再传给sed。

4 awk

(1) awk介绍

sed以行为单位处理文件,awk比sed强的地方在于不仅能以行为单位还能以列为单位处理文件。awk缺省的行分隔符是换行,缺省的列分隔符是连续的空格和Tab,但是行分隔符和列分隔符都可以自定义,比如/etc/passwd文件的每一行有若干个字段,字段之间以:分隔,就可以重新定义awk的列分隔符为:并以列为单位处理这个文件。@H_403_7@


@H_403_7@

(2) awk命令行格式

awk基本用法和sed类似,awk命令行的基本形式为:@H_403_7@

awk option 'script' file1 file2 ..@H_403_7@

awk option -f scriptfile file1 file2 ...@H_403_7@

和sed一样,awk处理的文件既可以由标准输入重定向得到,也可以当命令行参数传入,编辑命令可以直接当命令行参数传入,也可以用-f参数指定一个脚本文件,编辑命令的格式为:@H_403_7@

/pattern/{actions}@H_403_7@

condition{actions}@H_403_7@

pattern是正则表达式,actions是一系列操作(编辑命令),awk程序一行一行读出待处理文件,如果某一行与pattern匹配,或者满足condition条件,则执行相应的actions,如果一条awk命令只有actions部分,则actions作用于待处理文件的每一行。@H_403_7@


@H_403_7@

awk命令的condition部分还可以是两个特殊的condition-BEGIN和END,对于每个待处理文件,BEGIN后面的actions在处理整个文件之前执行一次,END后面的actions在整个文件处理完之后执行一次。@H_403_7@

@H_403_7@

(3) awk内建变量

awk命令可以像C语言一样使用变量(但不需要定义变量)。就像Shell的环境变量一样,有些awk变量是预定义的有特殊含义的:@H_403_7@

FILENAME@H_403_7@

当前输入文件文件名,该变量是只读的@H_403_7@

NR@H_403_7@

当前行的行号,该变量是只读的,R代表record@H_403_7@

NF@H_403_7@

当前行所拥有的列数,该变量是只读的,F代表field@H_403_7@

OFS@H_403_7@

输出格式的列分隔符,缺省是空格@H_403_7@

FS@H_403_7@

输入文件的列分融符,缺省是连续的空格和Tab@H_403_7@

ORS@H_403_7@

输出格式的行分隔符,缺省是换行符@H_403_7@

RS@H_403_7@

输入文件的行分隔符,缺省是换行符@H_403_7@

awk还可以像C语言一样使用if/else、while、for控制结构。以前未“系统”掌握awk命令格式时做的笔记(例子):shell awk读取文件中的指定行的指定字段。@H_403_7@


@H_403_7@

5 在C语言中使用的正则表达式

POSIX规定了正则表达式的C语言库函数:regex(3)。man regex。@H_403_7@

用正则表达式匹配字符串是否为IP地址的C代码:@H_403_7@

@H_403_7@

/*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}";
	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(&reg,regex,REG_EXTENDED | REG_NEWLINE);
	if ( 0 != re ) {
		regerror(re,&reg,errbuf,100);
		printf("%s\n",errbuf);
		exit(1);
	}

	//Use reg which compiled from pattern to match substring in whole string str
	re	= regexec(&reg,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 &reg used in recomp
	regfree(&reg);
	return 0;
}

编译并执行程序:@H_403_7@

gcc -o regex_in_c regex_in_c.c@H_403_7@

./regex_in_c@H_403_7@

matched:@H_403_7@

172.168.13.1@H_403_7@

0,12@H_403_7@

当在regcomp函数中的cflags参数中指定REG_NOSUB时nmatch和pmatch参数将会被忽略,不能再将它们的值输出来。@H_403_7@

[2014.8.11-21.02 ---- 2014.8.12-16.29]@H_403_7@

LCNote Over.@H_403_7@ 原文链接:/regex/361424.html

猜你在找的正则表达式相关文章