C++ 中的正则表达式 Regex

个人资料

原创
5
粉丝
3
喜欢
1
评论
0
等级:
访问:
1万+
积分:
179
排名:
104万+
C++ 中的正则表达式 Regex

注:下文所有内容仅仅适用于C++ 2011的新标准,相关编译环境为VS2010。

首先简单列举一下Regex表达式中的一些语法元素:

.

通配符,可匹配任何字符。

[]匹配中括号中的任何字符。
\d匹配所有数字字符。即:[0-9]
\D匹配所有非数字字符。即:[^0-9]
\s匹配所有空字符。
\w匹配所有字母、数字及下划线。

 

下面列举一下Regex表达式中的一些量词:

*匹配0个或多个。
+匹配1个或多个。
?匹配0个或1个。
{3}匹配3个。
{3,}匹配3个及以上。
{3,5}匹配3至5个。

在Regex中,量词默认是采用“贪心”原则。如要采用“非贪心”原则,可以在量词后面跟“?”。

<b>.*</b>匹配<b>x</b>y<b>z</b>

<b>.*?</b>匹配<b>x</b>y<b>z</b>

在Regex中,括号“()”用来确定优先级,以及确定Capture(捕获)。通常情况下,Capture(捕获)是无害的,但如果我们不希望Capture发生,可以使用以下语法:

 (?:whatever)

以上是Regex的语法的简单回顾。接着,我们来看一下C++中如何应用Regex相关库。

 

在C++中对应的Regex的Header File是<regex>

在Regex中真正的类型名是basic_regexregex仅仅是该类型模板对于char的一个类型别名。以下是一些常用的类型别名:

regexbasic_regex<char>
cmatchmatch_results<const char *>
smatchmatch_results<string::const_iterator>
csub_matchsub_match<const char *>
ssub_matchsub_match<string::const_iterator>

下面让我们来看一下match_resultssub_match的区别。

match_results表示对一个给定Regex表达式的匹配字符串,以及其所有的包含Capture。

sub_match表示对于一个Regex表达式中,一个Capture的匹配。

在Regex中,有3个常用函数,分别是regex_match()regex_search()regex_replace()

  1. // Sample Code for 'regex_match()'  
  2.   
  3. #include<iostream>  
  4. #include<regex>  
  5. using namespace std;  
  6. using namespace std::tr1;  
  7.   
  8. int _tmain(int argc, _TCHAR* argv[])  
  9. {  
  10.     regex r("[1-9]\\d*x[1-9]\\d*");  
  11.   
  12.     for (string s; getline(cin, s); ) {  
  13.         cout << (regex_match(s, r) ? "Yes" : "No") << endl;  
  14.     }  
  15. }  

执行用例:

8x10
>    Yes
1920x1200
>    Yes
3.14x137
>    No

以下是一个关于Capture的例子:

  1. // Sample Code for 'regex_match()' - (2)  
  2.   
  3. const regex r("([1-9]\\d*)x([1-9]\\d*)");  
  4.   
  5. for (string s; getline(cin, s); ) {  
  6.     smatch m;  
  7.   
  8.     if (regex_match(s, m, r)) {  
  9.         cout << m[1] << " by " << m[2] << endl; // 第0个Capture是整个Regex的匹配  
  10.     }  
  11. }  

执行用例:

1920x1200
>    1920 by 1200

  1. // Sample Code for 'regex_replace()'  
  2.   
  3. const regex r("(\\w+)( \\w+\\.?)? (\\w+)");  
  4. const string fmt("$3, $1$2");  
  5.   
  6. for (string s; getline(cin, s); ) {  
  7.     cout << "*** " << regex_replace(s, r, fmt) << endl;  
  8. }  

执行用例:

Stephan T. Lavavej
>    *** Lavavej, Stephan T.
Stephan Thomas Lavavej
>    *** Lavavej, Stephan Thomas
Stephan Lavavej
>    *** Lavavej, Stephan

这里在Format字符串中引用了匹配中的Capture,以下是一个详表:

Regex: ([A-Z]+)-([0-9]+)

String:  2161-NCC-1701-D

$1第1个CaptureNCC
$2第2个Capture1701
$&整个Regex的匹配NCC-1701
$`这个Regex的前缀2161-
$'这个Regex的后缀-D
$$字符“$”$

 

补充一下关于 正向预查 与 负向预查 的语法:

(?=SubPattern)

正向预查

在这个预查模式之后的字符串必须符合该预查模式,但其不消耗字符。

(?!SubPattern)

负向预查

在这个预查模式之后的字符串必须符合该预查模式,但其不消耗字符。

以下是一个例子:

Regex: ([1-9]\d*|0)(\.\d+)?|0[xX][0-9a-zA-Z]

对于上述模式,在匹配十六进制数时会遇到问题。“0x1”中的“0”先会被匹配,之后的“x”便无法被成功识别。在这里便可以使用 负向预查 来消除上述错误。以下是可用版本。

Regex: ([1-9]\d*|0(?![xX]))(\.\d+)?|0[xX][0-9a-zA-Z]

更改之后,在0之后不希望出现x或X。如此,便可以避免“0x1”中的“0”被前一个模式“吃”掉的情况。

 

以下Link是一个关于Regex语法(ECMAScript Grammar)的参考。

http://cplusplus.com/reference/std/regex/ECMAScript/

 

阅读更多
个人分类: C++
想对作者说点什么? 我来说一句
空气能加盟选碧涞,0加盟费让您更放心碧涞节能 · 顶新
农村有一宝,可治痔疮,可惜很少人知道!!嘉泰 · 顶新

C++ regex

1、C++正则表达式 2、

liminled liminled

2014-08-07 16:21:17

阅读数:4013

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
登录
阅读更多
个人分类: bishi
想对作者说点什么? 我来说一句

C++Regex正则表达式

2015年01月30日 128KB 下载

没有更多推荐了,返回首页

不良信息举报

C++ 中的正则表达式 Regex

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭