① 正则表达式特殊符号及用法
Python3 正则表达式特殊符号及用法(详细列表)
正则表达式的强大之处在于特殊符号的应用,特殊符号定义了字符集合、子组匹配、模式重复次数。正是这些特殊符号使得一个正则表达式可以匹配字符串集合而不只是一个字符串。
注1:为了便于理解,难点的地方均用 斜体 举了栗子。
注2:如果你对正则表达式一头雾水或者看不懂下边这个列表,那么小甲鱼极力推荐你先学习这个: Python3 如何优雅地使用正则表达式
字蚂卖符 含义
. 表示匹配除了换行符外的任何字符
注:通过设置 re.DOTALL 标志可以使 . 匹配任何字符(包含换行符)
A | B, 表示匹配正则表达式 A 或者 B
^ 1. (脱字符)匹配输入字符串的开始位置
2. 如果设置了 re.MULTILINE 标志,^ 也匹配换行符之后的位置
$ 1. 匹配输入字符串的结束位置
2. 如果设置了 re.MULTILINE 标志,$ 也匹配换行符之前的位置
\ 1. 将一个普通字符变成特殊字符,例如 \d 表示匹配所有十进制数字
2. 解除元字符的特殊功能,例如 \. 表示匹配点号本身
3. 引用序号对应的子组所匹配的字符串
4. 详见下方列举
[...] 字符类,匹配所包含的任意一个字符
注1:连字符 - 如果出现在字符串中间表示字符范围描述;如果如果出现在首位则仅作为普通字符
注2:特殊字符仅有反斜线 \ 保持特殊含义,用于转义字符。其它特殊字符如 *、+、? 等均作为普通字符匹配
注3:脱字符 ^ 如果出现在首位则表示匹配不包含其中的任意字符;如果 ^ 出现在字符串中间就仅作为普通字符匹配
{M,N} M 和 N 均为非负整数,其中 M <= N,表示前边的 RE 匹配 M ~ N 次
注1:{M,} 表示至少匹配 M 次
注2:{,N} 等价于 {0,N}
注3:{N} 表示需要匹配 N 次
* 匹配前面的子表达式零次或多次,等价于 {0,}
+ 匹配前面的子表达式一次或多次,等价于 {1,}
? 匹配前面的子表达式零次或一次,等价于 {0,1}
*?, +?, ??默认情况下 *、+ 和 ? 的匹配模式是贪婪模式(即会尽可能多地匹配符合规则的字符串);*?、+? 和 ?? 表示启用对应的非贪婪模式。
举个栗子:对于字符串 "FishCCC",正则表达式 FishC+ 会匹配整个字符串,而 FishC+? 则匹配 "FishC"。
{M,N}? 同上,启用非贪婪模式,即只匹配 M 次
(...) 匹配圆括号中的正则表达式,或者指定一个子组的开始和结束位置
注:子组的内容可以在匹配之后被 \数字 再次引用
举个栗子:(\w+) \1 可以字符串 "FishC FishC.com" 中的 "FishC FishC"(注意有空格)
(?...)(? 开头的表示为正则表达式的扩展语法(下边这些是 Python 支持的所有扩展语法)
(?aiLmsux)1. (? 后可以紧跟着 'a','i','L','m','s','u','x' 中的一个或多个字符,只能在正则表达式的开头使用
2. 每一个字符对应一种匹配标志:re-A(只匹配 ASCII 字符),re-I(忽略大小写),re-L(区域设置),re-M(多行模式), re-S(. 匹配任何符号),re-X(详细表达式),包含这些字符将会影响整个正则表达式的规则
3. 当你不想通过 re.compile() 设置正则表达式标志,这种方法就非常有用啦
注意,由于 (?x) 决定正则表达式如何被解析,所以它应该总是被放在最前边(最多允许前边有空白符)。如果 (?x) 的前边是非空白字符,那么 (?x) 就发挥不了作用了。
(?:...)非捕获组,即该子组匹配的字符串无法从后边获取
(?P<name>...)命名组,通过组的名字(name)即可访问到子组匹配的字符串
(?P=name)反向引用一个命名组,它匹配指定命名组匹配的任何孙物州内容
(?#...)注释,括号中的内容将被忽略
(?=...)前向肯定断言。如果当前包含的正则表达式(这里以 ... 表示)在当前位置成功匹配,则代表成功,否则失败。一旦该部分正则表达式被匹配引擎尝试过,就不会继续进行匹配则蔽了;剩下的模式在此断言开始的地方继续尝试。
举个栗子:love(?=FishC) 只匹配后边紧跟着 "FishC" 的字符串 "love"
(?!...)前向否定断言。这跟前向肯定断言相反(不匹配则表示成功,匹配表示失败)。
举个栗子:FishC(?!\.com) 只匹配后边不是 ".com" 的字符串 "FishC"
(?<=...)后向肯定断言。跟前向肯定断言一样,只是方向相反。
举个栗子:(?<=love)FishC 只匹配前边紧跟着 "love" 的字符串 "FishC"
(?<!...)后向否定断言。跟前向肯定断言一样,只是方向相反。
举个栗子:(?<!FishC)\.com 只匹配前边不是 "FishC" 的字符串 ".com"
(?(id/name)yes-pattern|no-pattern)1. 如果子组的序号或名字存在的话,则尝试 yes-pattern 匹配模式;否则尝试 no-pattern 匹配模式
2. no-pattern 是可选的
举个栗子:(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$) 是一个匹配邮件格式的正则表达式,可以匹配 和 '[email protected]',但是不会匹配 ''
\下边列举了由字符 '\' 和另一个字符组成的特殊含义。注意,'\' + 元字符的组合可以解除元字符的特殊功能
\序号1. 引用序号对应的子组所匹配的字符串,子组的序号从 1 开始计算
2. 如果序号是以 0 开头,或者 3 个数字的长度。那么不会被用于引用对应的子组,而是用于匹配八进制数字所表示的 ASCII 码值对应的字符
举个栗子:(.+) \1 会匹配 "FishC FishC" 或 "55 55",但不会匹配 "FishCFishC"(注意,因为子组后边还有一个空格)
\A匹配输入字符串的开始位置
\Z匹配输入字符串的结束位置
\b匹配一个单词边界,单词被定义为 Unidcode 的字母数字或下横线字符
举个栗子:\bFishC\b 会匹配字符串 "love FishC"、FishC." 或 "(FishC)"
\B匹配非单词边界,其实就是与 \b 相反
举个栗子:py\B 会匹配字符串 "python"、"py3" 或 "py2",但不会匹配 "py "、"py." 或 "py!"
\d1. 对于 Unicode(str 类型)模式:匹配任何一个数字,包括 [0-9] 和其他数字字符;如果开启了 re.ASCII 标志,就只匹配 [0-9]
2. 对于 8 位(bytes 类型)模式:匹配 [0-9] 中任何一个数字
\D匹配任何非 Unicode 的数字,其实就是与 \d 相反;如果开启了 re.ASCII 标志,则相当于匹配 [^0-9]
\s1. 对于 Unicode(str 类型)模式:匹配 Unicode 中的空白字符(包括 [ \t\n\r\f\v] 以及其他空白字符);如果开启了 re.ASCII 标志,就只匹配 [ \t\n\r\f\v]
2. 对于 8 位(bytes 类型)模式:匹配 ASCII 中定义的空白字符,即 [ \t\n\r\f\v]
\S匹配任何非 Unicode 中的空白字符,其实就是与 \s 相反;如果开启了 re.ASCII 标志,则相当于匹配 [^ \t\n\r\f\v]
\w1. 对于 Unicode(str 类型)模式:匹配任何 Unicode 的单词字符,基本上所有语言的字符都可以匹配,当然也包括数字和下横线;如果开启了 re.ASCII 标志,就只匹配 [a-zA-Z0-9_]
2. 对于 8 位(bytes 类型)模式:匹配 ASCII 中定义的字母数字,即 [a-zA-Z0-9_]
\W匹配任何非 Unicode 的单词字符,其实就是与 \w 相反;如果开启了 re.ASCII 标志,则相当于 [^a-zA-Z0-9_]
转义符号正则表达式还支持大部分 Python 字符串的转义符号:\a,\b,\f,\n,\r,\t,\u,\U,\v,\x,\\
注1:\b 通常用于匹配一个单词边界,只有在字符类中才表示“退格”
注2:\u 和 \U 只有在 Unicode 模式下才会被识别
注3:八进制转义(\数字)是有限制的,如果第一个数字是 0,或者如果有 3 个八进制数字,那么就被认为是八进制数;其他情况则被认为是子组引用;至于字符串,八进制转义总是最多只能是 3 个数字的长度
② 求教C#正则表达式
什么是正则表达式
在编写字符串的处理程序时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说或羡,正则表达式就是记录文本规则的代码。
通常,我们在使用WINDOWS查找文件时,会使用通配符(*和?)。如果你想查找某个目录下的所有Word文档时,你就可以使用*.doc进行查找,在这里,*就被解释为任意字符串。和通配符类似,正则衫仔拍表达式也是用来进行文本匹配的工具,只不过比起通配符,它能更精确地描述你的需求——当然,代价就是更复杂。
l 一个简单的例子——验证电话号码
学习正则表达式的最好方法是从例子开始,下面我们从验证电话号码开始,一步一步的了解正则表达式。
在我们国家,电话号码(如:0379-65624150)通常包含3到4为以0开头的区号和一个7或8为的号码,中间通常以连字符’-’隔开。在这个例子中,首先我们要介绍一个元字符\d,它用来匹配一个0到9的数字。这个正则表达式可以写成:^0\d{2,3}-\d{7,8}$
我们来对他进行分析,0匹配数字“0”,\d匹配一个数字,{2,3}表示重复2到3次,-只匹配”-”自身,接下来的\d同样匹配一个数字,而 {7,8}则表示重复7到8次。当然,电话号码还可以写成 (0379)65624150,这里就交给读者完成。
l 元字符
在上面的例子中,我们接触到了一个元字符\d,正如你所想的,正则表达式还有很多像\d一样的元字符,下表列出了一些常用的元字符:
元字符
说明
.
匹配除换行符以外的任意字符
\b
匹配单词的开始或结束
\d
匹配数字
\s
匹配任意的空白符
\w
匹配字母或数字或下划线或汉字
^
匹配字符串的开始
$
匹配字符串的结束
表1、常用的元字符
l 转义字符
如果你想查找元字符本身的话,比如你查找.,或者*,就出现了问题:你没办法指定它们,因为它们会被解释成别的意思。这时你就得使用\来取消这些字符的特殊意义。因此,你应该使用\.和\*。当然,要查找\本身,你也得用\\.
例如:unibetter\.com匹配unibetter.com,C:\\Windows匹配C:\Windows。
l 限定符
限定符又叫重复描述字符,表示一个字符要出现的次数。比如我们在匹配电话号码时使用的{3,4}就表示出现3到4次。常用的限定符有:
限定符
说明
*
重复零次或更多次
+
重复一次或更多次
?
重复零次或一次
{n}
重复n次
{n,}
重复n次或更多次
{n,m}
重复n到m次
表2、常用的限定符
二、.NET中正则表达式的支持
System.Text.RegularExpressions 命名空间包含一些类,这些类提供对 .NET Framework 正则表达式引擎的访问。该命名空间提供正则表达式功能,可以从运行在 Microsoft .NET Framework 内的任何平台或语言中使用该功能。
1、在C#中使用正则表达式
在了解了C#中支持正则表达式的类后,我们一起来将上面提到的验证电话号码的正则表达式写入C#代码中,实现电话号码的验证。
第一步,建立一个名为SimpleCheckPhoneNumber的Windows项目。
第二步,引入System.Text.RegularExpressions命名空间。
第三步,写戚纯出正则表达式。这里的正则表达式就是上面的验证号码的字符串。由于上面的字符串只能验证用连字符连接区号和号码的方式的电话号码,所以我们做了一些修改:0\d{2,3}-\d{7,8}|\(0\d{2,3}\)\d{7,8}。在这个表达式中,| 号面的一部分是我们上面提到过的,后面一部分是用来验证(0379)65624150这种电话号码写法的。由于 ( 和 ) 也是元字符,所以要用转义字符。| 表示分支匹配,要么匹配前面的一部分,要么匹配后面的一部分。
第四步,正则表达式构造一个Regex类。
第五步,使用Regex类的IsMatch方法验证匹配。Regex类的IsMatch()方法返回一个bool值,如果有匹配项,返回true,否则返回false。
、正则表达式进阶
l 分组
在匹配电话号码的时候,我们已经用到过重复单个字符。下面我们来了解如何使用分组来匹配一个IP地址。
众所周知,IP地址是四段点分十进制的字符串表示的。所以,我们可以通过地址的分组,来进行匹配。首先,我们来匹配第一段:2[0-4]\d|25[0-5]|[01]?\d\d? 这段正则表达式可以匹配IP地址的一段数字。2[0-4]\d 匹配以2开头,十位为0到4,个位为任何数字的三位字段,25[0-5] 匹配以25 开头,个位为0到5 的三位字段,[01]?\d\d? 匹配任何以1者0头,个位和十位为任何数子的字段。? 表示出现零次或一次。所以, [01] 和 最后一个 \d 都可以不出现,如果我们再向这个字符串后面添加一个 \. 来匹配 . 就可以划分一个段了。现在,我们把 2[0-4]\d|25[0-5]|[01]?\d\d?\. 当做一个分组,就可以写成 (2[0-4]\d|25[0-5]|[01]?\d\d?\.) 。接下来我们就来使用这个分组。将这个分组重复两次,然后,再使用 2[0-4]\d|25[0-5]|[01]?\d\d? 就可以了。完整的正则表达式为: (2[0-4]\d|25[0-5]|[01]?\d\d?\.){3}2[0-4]\d|25[0-5]|[01]?\d\d?
l 后向引用
在我们了解分组以后,我们就可以使用后向引用了。所谓后向引用,就是使用前面捕获的结果,对后面的字符进行匹配。多用于匹配重复字符。比如匹配 go go 这样的重复字符。我们就可以使用 (go) \1来进行匹配。
默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。当然,你也可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?<Word>\w+)(或者把尖括号换成'也行:(?'Word'\w+)),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k<Word>,所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b。
自定义组名还有另外一个好处,在我们的C#程序中,如果需要得到分组的值,我们就可以很明确的使用我们定义的分组的名字来得到,而不必使用下标。
当我们并不想使用后向引用时,是不需要捕获组记忆任何东西的,这种情况下就可以利用(?:nocapture)语法来主动地告诉正则表达式引擎,不要把圆括号的内容当作捕获组,以便提高效率。
l 零宽断言
在前面的元字符介绍中,我们已经知道了有这样一类字符,可以匹配一句话的开始、结束(^ $)或者匹配一个单词的开始、结束(\b)。这些元字符只匹配一个位置,指定这个位置满足一定的条件,而不是匹配某些字符,因此,它们被成为 零宽断言。所谓零宽,指的是它们不与任何字符相匹配,而匹配一个位置;所谓断言,指的是一个判断。正则表达式中只有当断言为真时才会继续进行匹配。
在有些时候,我们精确的匹配一个位置,而不仅仅是句子或者单词,这就需要我们自己写出断言来进行匹配。下面是断言的语法:
断言语法
说明
(?=pattern)
前向肯定断言,匹配pattern前面的位置
(?!pattern)
前向否定断言,匹配后面不是pattern的位置
(?<=pattern)
后向肯定断言,匹配pattern后面的位置
(?<!pattern)
后向否定断言,匹配前面不是pattern的位置
表3、断言的语法及说明
很难理解吗?我们来看一个例子。
有一个标签:<book>,我们想要得到标签<book>的标签名(book),这个时候,我们就可以使用断言来处理。看下面这个表达式:(?<=\<)(?<tag>\w*)(?=\>) ,使用这个表达式,可以匹配< 和 >之间的字符,也就是这里的book。使用断言还还可以写出更加复杂的表达式,这里就不再举例了。
还有一点非常重要,就是断言语法所使用的圆括号并不作为捕获组,所以不能使用编号或命名来对它进行引用。
l 贪婪与懒惰
当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。来看一下这个表达式:a\w*b ,用它来匹配字符串 aabab 时,得到的匹配结果是 aabab 。这种匹配被称为贪婪匹配。
有些时候,我们希望让它尽可能的少重复,即用上面的例子得到的匹配结果是 aab,这时我们就要使用懒惰匹配。懒惰匹配需要在重复限定符的后面添加一个 ? 符号,上面的表达式就可以写成:a\w*?b 我们再来匹配字符串 aabab时,得到的匹配结果是 aab 和 ab。
也许这个时候你要问,ab 比aab重复次数更少,为什么不先匹配ab呢?其实在正则表达式中还有比贪婪/懒惰优先级更高的规则:最先开始的匹配拥有最高的优先权——The match that begins earliest wins。
l 注释
语法:(?#comment)
例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)
注意:如果使用注释,则需要格外注意不要在注释的小括号前面出现空格、换行符等一些字符,如果可以忽略这些字符,则最好使用“忽略模式里的空白符”选项,即C#中RegexOptions枚举的IgnorePatternWhitespace选项(C#中的RegexOptions枚举下面将会提到)。
l C#中的处理选项
在C#中,可以使用RegexOptions 枚举来选择C#对正则表达式的处理方式。下面是MSDN中RegexOptions 枚举的成员介绍:
l C#中Capture类、Group类、Match类
Capture类:表示单个子表达式捕获中的结果。Capture类表示单个成功捕获中的一个子字符串。该类没有公共构造函数,可以从Group类或者Match类中得到一个Capture类的对象集合。Capture类有三个常用属性,分别是Index、Length和Value。Index表示捕获的子字符串的第一个字符的位置。Length表示捕获的子字符串的长度,Value表示捕获的子字符串。
Group类:表示正则表达式中分组的信息。该类提供了对分组匹配的正则表达式的支持。该类没有公共构造函数。可以从Match类中得到一个Group类的集合。如果正则表达式中的分组已命名,则可以使用名字对其进行访问,如果没有命名,则可以采用下标访问。注意:每一个Match的Groups集合中的第0个元素(Groups[0])都是这个Match捕获的字符串,也是Capture的Value。
Match类:表示单个正则表达式匹配的结果。该类同样没有公共构造函数,可以从Regex类的Match()方法得到该类的一个实例,也可以使用Regex类的Matches()方法得到给类的一个集合。
这三个类都能表示单个正则表达式匹配的结果,但Match类得到的更为详细,包含捕获和分组信息。所以,Match类在这个三个类中是最常用的。
③ C语言怎么用正则表达式
由于它可以极大地简化处理字符串时的掘咐漏复杂度,因此现在已经在许多 L i n u x 实用工具中得到了应用。千万不要以为正则表达式只是 P e r l 、 P y t h o n 、 B a s h 等脚本语言的专利,作为 C 语言程序员,用户同样可以在自己的程序中运用正则表达式。标准的 C 和 C + + 都不支持正则表达式,但有一些函数库可以辅助 C / C + + 程序员完成这一功能,其中最着名的当数 P h i l i p H a z e l 的 P e r l - C o m p a t i b l e R e g u l a r E x p r e s s i o n 库,许多 L i n u x 发行版本都带有这个函数库。编译正则表达式为了提高效率,在将一个字符串与正则表达式进行比较之前,首先要用 r e g c o m p ( ) 函数对它进行编译,将其转化为 r e g e x _ t 结构: i n t r e g c o m p ( r e g e x _ t * p r e g , c o n s t c h a r * r e g e x , i n t c f l a g s ) ; 参数 r e g e x 是一个字符串,它代表将要被编译的正则表达式;参数 p r e g 指向一个声明为 r e g e x _ t 的数据结构,用来保存编译结果;参数 c f l a g s 决定了正则表达式该如何被处理的细节。判烂如果函数 r e g c o m p ( ) 执行成功,并且编译结果被正确填充到 p r e g 中后,函数将返回 0 ,任何其它的返回结果都代表有某种错简烂误产生。匹配正则表达式一旦用 r e g c o m p ( ) 函数成功地编译了正则表达式,接下来就可以调用 r e g e x e c ( ) 函数完成模式匹配: i n t r e g e x e c ( c o n s t r e g e x _ t * p r e g , c o n s t c h a r * s t r i n g , s i z e _ t n m a t c h , r e g m a t c h _ t p m a t c h [ ] , i n t e f l a g s ) ; t y p e d e f s t r u c t { r e g o f f _ t r m _ s o ; r e g o f f _ t r m _ e o ; } r e g m a t c h _ t ; 参数 p r e g 指向编译后的正则表达式,参数 s t r i n g 是将要进行匹配的字符串,而参数 n m a t c h 和 p m a t c h 则用于把匹配结果返回给调用程序,最后一个参数 e f l a g s 决定了匹配的细节。在调用函数 r e g e x e c ( ) 进行模式匹配的过程中,可能在字符串 s t r i n g 中会有多处与给定的正则表达式相匹配,参数 p m a t c h 就是用来保存这些匹配位置的,而参数 n m a t c h 则告诉函数 r e g e x e c ( ) 最多可以把多少个匹配结果填充到 p m a t c h 数组中。当 r e g e x e c ( ) 函数成功返回时,从 s t r i n g + p m a t c h [ 0 ] . r m _ s o 到 s t r i n g + p m a t c h [ 0 ] . r m _ e o 是第一个匹配的字符串,而从 s t r i n g + p m a t c h [ 1 ] . r m _ s o 到 s t r i n g + p m a t c h [ 1 ] . r m _ e o ,则是第二个匹配的字符串,依此类推。释放正则表达式无论什么时候,当不再需要已经编译过的正则表达式时,都应该调用函数 r e g f r e e ( ) 将其释放,以免产生内存泄漏。 v o i d r e g f r e e ( r e g e x _ t * p r e g ) ; 函数 r e g f r e e ( ) 不会返回任何结果,它仅接收一个指向 r e g e x _ t 数据类型的指针,这是之前调用 r e g c o m p ( ) 函数所得到的编译结果。如果在程序中针对同一个 r e g e x _ t 结构调用了多次 r e g c o m p ( ) 函数, P O S I X 标准并没有规定是否每次都必须调用 r e g f r e e ( ) 函数进行释放,但建议每次调用 r e g c o m p ( ) 函数对正则表达式进行编译后都调用一次 r e g f r e e ( ) 函数,以尽早释放占用的存储空间。报告错误信息如果调用函数 r e g c o m p ( ) 或 r e g e x e c ( ) 得到的是一个非 0 的返回值,则表明在对正则表达式的处理过程中出现了某种错误,此时可以通过调用函数 r e g e r r o r ( ) 得到详细的错误信息。 s i z e _ t r e g e r r o r ( i n t e r r c o d e , c o n s t r e g e x _ t * p r e g , c h a r * e r r b u f , s i z e _ t e r r b u f _ s i z e ) ; 参数 e r r c o d e 是来自函数 r e g c o m p ( ) 或 r e g e x e c ( ) 的错误代码,而参数 p r e g 则是由函数 r e g c o m p ( ) 得到的编译结果,其目的是把格式化消息所必须的上下文提供给 r e g e r r o r ( ) 函数。在执行函数 r e g e r r o r ( ) 时,将按照参数 e r r b u f _ s i z e 指明的最大字节数,在 e r r b u f 缓冲区中填入格式化后的错误信息,同时返回错误信息的长度。应用正则表达式最后给出一个具体的实例,介绍如何在 C 语言程序中处理正则表达式。 # i n c l u d e < s t d i o . h > ; # i n c l u d e < s y s / t y p e s . h > ; # i n c l u d e < r e g e x . h > ; / * 取子串的函数 * / s t a t i c c h a r * s u b s t r ( c o n s t c h a r * s t r , u n s i g n e d s t a r t , u n s i g n e d e n d ) { u n s i g n e d n = e n d - s t a r t ; s t a t i c c h a r s t b u f [ 2 5 6 ] ; s t r n c p y ( s t b u f , s t r + s t a r t , n ) ; s t b u f [ n ] = 0 ; r e t u r n s t b u f ; } / * 主程序 * / i n t m a i n ( i n t a r g c , c h a r * * a r g v ) { c h a r * p a t t e r n ; i n t x , z , l n o = 0 , c f l a g s = 0 ; c h a r e b u f [ 1 2 8 ] , l b u f [ 2 5 6 ] ; r e g e x _ t r e g ; r e g m a t c h _ t p m [ 1 0 ] ; c o n s t s i z e _ t n m a t c h = 1 0 ; / * 编译正则表达式 * / p a t t e r n = a r g v [ 1 ] ; z = r e g c o m p ( & r e g , p a t t e r n , c f l a g s ) ; i f ( z ! = 0 ) { r e g e r r o r ( z , & r e g , e b u f , s i z e o f ( e b u f ) ) ; f p r i n t f ( s t d e r r , " % s : p a t t e r n ' % s ' \ n " , e b u f , p a t t e r n ) ; r e t u r n 1 ; } / * 逐行处理输入的数据 * / w h i l e ( f g e t s ( l b u f , s i z e o f ( l b u f ) , s t d i n ) ) { + + l n o ; i f ( ( z = s t r l e n ( l b u f ) ) > ; 0 & & l b u f [ z - 1 ] = = ' \ n ' ) l b u f [ z - 1 ] = 0 ; / * 对每一行应用正则表达式进行匹配 * / z = r e g e x e c ( & r e g , l b u f , n m a t c h , p m , 0 ) ; i f ( z = = R E G _ N O M A T C H ) c o n t i n u e ; e l s e i f ( z ! = 0 ) { r e g e r r o r ( z , & r e g , e b u f , s i z e o f ( e b u f ) ) ; f p r i n t f ( s t d e r r , " % s : r e g c o m ( ' % s ' ) \ n " , e b u f , l b u f ) ; r e t u r n 2 ; } / * 输出处理结果 * / f o r ( x = 0 ; x < n m a t c h & & p m [ x ] . r m _ s o ! = - 1 ; + + x ) { i f ( ! x ) p r i n t f ( " % 0 4 d : % s \ n " , l n o , l b u f ) ; p r i n t f ( " $ % d = ' % s ' \ n " , x , s u b s t r ( l b u f , p m [ x ] . r m _ s o , p m [ x ] . r m _ e o ) ) ; } } / * 释放正则表达式 * / r e g f r e e ( & r e g ) ; r e t u r n 0 ; } 上述程序负责从命令行获取正则表达式,然后将其运用于从标准输入得到的每行数据,并打印出匹配结果。执行下面的命令可以编译并执行该程序: # g c c r e g e x p . c - o r e g e x p # . / r e g e x p ' r e g e x [ a - z ] * ' < r e g e x p . c 0 0 0 3 : # i n c l u d e < r e g e x . h > ; $ 0 = ' r e g e x ' 0 0 2 7 : r e g e x _ t r e g ; $ 0 = ' r e g e x ' 0 0 5 4 : z = r e g e x e c ( & r e g , l b u f , n m a t c h , p m , 0 ) ; $ 0 = ' r e g e x e c ' 小结对那些需要进行复杂数据处理的程序来说,正则表达式无疑是一个非常有用的工具。本文重点在于阐述如何在 C 语言中利用正则表达式来简化字符串处理,以便在数据处理方面能够获得与 P e r l 语言类似的灵活性。
④ 正则表达式“或“的使用
正则表达式,又称规则表达式。是计算机科学的一个概念。
正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正模搏旦则表达式引擎。正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。
正则表达式通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen。
(4)c正则表达式使用方法扩展阅读
正则表达式的作用:
1、匹配
检查字符串是否符合正则表达式中的规则,有一次不匹配,则返回false。如:
String str="abc";
String reg="[a-zA-Z]\d?";//次表达式表示字符串的第一位只能是字母,第银冲二位只能是数字或没有boolean flag=str.matches(reg);//返回结果为true。
2、切割
所谓切割,即是按一定的规则将字符串分割成多个子字符串,如:
String str="zhangsan,lishi,wangwu"。
String reg=",";//表示以逗号作为切割符。
String[] arr=str.split(reg);//返回结果为{“zhangsan”,"lisi","wangwu}。
3、替换
即将字符串中符合规则的字符替换成指定字符,如:
String str=""。
str.replaceAll("\d{3,}","#");//表示将连续出现三个或三个以上的数字替换成“#”。
⑤ 正则表达式
regular expression是计算机科学中的一个概念。正则表达式使用单个字符串来描述匹配一系列符合某个句法规则的字符串。
g全文搜索,敏谨i忽略大小写,m多行搜索
具有特殊意义的专用字符,用来规定其前导字符
( [ { ^ $ | ) ? * + .
不同组合中的元字符有不同的意义,举例
可以使用[]来构建一个简单的类
var reg = /[abc123]/;
创建一个单字符的类,代表这个字符可以是a,可以是b,可以是c,可以是1,...可以是3。
可以使用^来进行取反,
var reg = /[^abc123]/;
代表着这个单字符可以是任何其他的单字符,除了a,b,c,1,2,3之外。
如果要匹配单个字符,让单字符只能取数字的话,可以使用字符类
写成:
var reg = /[0123456789]/;
这么写比较麻烦,所以可以使用范围类,我们可以使用x-y来连接两个字符,表示从x到y的任意字符,是个 闭区间 ,意味着 包含x和y本身 ,这样,我们要匹配单个数字就可以写成:
var reg2 = /[0-9]/;
要匹配所以的单个字母,可以写为
var reg3 = /[a-zA-Z]/;
上面创建了一些类,用来表示数组,字母等。但是这么写也比较麻烦,正则表达式提供了几个常见的预定义类来匹配常见的字符
有了这些预定义类,写一些正则就比较方便了,比如我们希望匹配一个ab+数字+任意字符的字符串,就可以写作:
var reg = /abd./;
正则表达式还提供了几个常用的边界匹配字符
^如果不写在[]内的话,不代表取反,代表以xxx开头,例如: var reg = /hello/; 代表以hello开头,相应的也有$表示为以xxx结尾,举例说明:
单词边界
之前写的方法都是一一匹配的,但是如果希望匹配一个连续出现很多次的字符,例如数字的字符串,不需要写成 dddd ,我们可以使用量词
使用举例:
上面提到的{n,m},如果出现多次,只要是n-m中的值都满足条件,到底是按照n还是m来匹配。 量词在默认条件下是尽可能多的匹配的,即默认贪婪模式
var reg = /d{3,5}/g; '.match(reg); //{"12345","6789"}
与贪婪模式相对的,就有非贪婪模式,即尽可能少的匹配,一旦成功匹配之后不再继续尝试,在后面加上?即可
var reg2 = /d{3,5}?/g; '.match(reg); //{"12345","6789"}
上面的量词解决的是单个字符重复多次的问题,如果我们需要匹配重复的多个字符,比如匹配hello出现20次,如果写成hello{20}意味着是hell+o出现20次,o自己重复20次,而不是整个hello重复20次。
我们可以使用分组()来解备桥决这个问题,写成:
/(hello){20}/g;
对于上面的情况,如果我们希望匹配hello或者world出现20次,可以通过使用 | 进行或操作
/(hello|world){20}/g;
举例: good(?=Bayon) 匹配后面有Bayon的good
检测字符串参数中是否存在正则表达式模式,存在返回true不存在返回false
用于正则表达式模式在字符串中运行查找,如果exec()找到了匹配的文本,则返回一个结果数组,否则返回null
除了数组元素和length属性之外,exec()方法返回对象还包桥滚基括两个属性。
举例说明:
search()方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。
search方法不执行全局匹配,它将忽略标志g,同时也忽略正则表达式对象的lastIndex属性,总是返回字符串的第一个匹配的位置
match()方法将检索字符串,以找到一个或者多个与regexp匹配的文本。regexp是否有全局g标志会影响结果。
关于string对象的replace方法,一般可以传入两个字符串,但是只能replace一次,如果把第一个参数传入regexp的话,就可以是replace变得灵活。
经常使用split方法把字符串分割为字符数组
'a,b,c,d'.split(","); // ["a","b","c","d"];
相应的,也可以使用regexp进行切割:
"a1b2c3".split(/d/); // ["a","b","c","d"]
⑥ C++ 怎样用正则表达,,
1)首先这个错误是在于抛出了一个regex_error的异常,你捕获一下就可烂埋以了
2)在用字符串表示regex的时候,注意在字符串中间,\是反义字符,”\D"表示对D的转移,显然是错误的,所以如果要表示\D的正则需要使用“\\D",同样{也是关键字符,表饥扮蚂示为“\\{"
3)然后我测试了一缺手下(?<=<expr>)语法是regex库解析是不支持的,我给改为了下面的pattern,是可以用的:
regex pattern(".*\\}(\\D+)\\{.*");
char* buffer="{ffff}hello world!{ffff}";
cmatch m;
if(regex_match(buffer,m,pattern))
{
for(int i=0; i<what.size(); i++)
cout<<"str :"<<what[i].str()<<endl;
}
⑦ 如何使用正则表达式匹配C语言的变量名定义规则
需要使用一个字符串作为c语言中的变量名,这个字符森肆串岁轿必须满足下面的要求:
1.只包含数字,ASCII字母,下划线
2.以字母乎春肆或者下划线开头