c++ 正則表達式

正則表達式是经常使用的一种方法。比較有名的类库是boost,可是这个类库在重了。全部就像找一些轻量级的类库。

后来发现准标准的库tr1已经非常方便了,微软vs2008 sp1 以上版本号都支持了。全部就直接用它非常方便了。

并且支持unicode编码,还是非常方便的。

样例:

#include <iostream>

#include <string>

#include <regex>

int _tmain(int argc, _TCHAR* argv[])

{

std::locale loc("");

std::wcout.imbue(loc);

std::wstring text(_T("我的IP地址是:109.168.0.1."));

std::wstring newIP(_T("127.0.0.1"));

std::wstring regString(_T("(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"));

// 表达式选项 - 忽略大写和小写

std::regex_constants::syntax_option_type fl = std::regex_constants::icase;

// 编译一个正則表達式语句

std::wregex regExpress(regString, fl);

// 保存查找的结果

std::wsmatch ms;

// 推断是否全行匹配

if(std::regex_match(text, ms, regExpress))

{

std::wcout<<_T("正則表達式:")<<regString<<_T("匹配:")<<text<<_T("成功.")<<std::endl;

}

else

{

std::wcout<<_T("正則表達式:")<<regString<<_T("匹配:")<<text<<_T("失败.")<<std::endl;

}

// 查找

if(std::regex_search(text, ms, regExpress))

{

std::wcout<<_T("正則表達式:")<<regString<<_T("查找:")<<text<<_T("成功.")<<std::endl;

for(size_t i= 0; i < ms.size(); ++i)

{

std::wcout<<_T("第")<<i<<_T("个结果:\"")<<ms.str(i)<<_T("\" - ");

std::wcout<<_T("起始位置:")<<ms.position(i)<<_T("长度")<<ms.length(i)<<std::endl;

}

std::wcout<<std::endl;

// 替换1

text = text.replace(ms[0].first, ms[0].second, newIP);

std::wcout<<_T("替换1后的文本:")<<text<<std::endl;

}

else

{

std::wcout<<_T("正則表達式:")<<regString<<_T("查找:")<<text<<_T("失败.")<<std::endl;

}

// 替换2

newIP = _T("255.255.0.0");

std::wstring newText = std::regex_replace( text, regExpress, newIP);

std::wcout<<_T("替换2后的文本:")<<newText<<std::endl;

// 结束

std::wcout<<_T("按回车键结束...");

std::wcin.get();

return 0;

}

循环取:

std::regex_constants::syntax_option_type fl = std::regex_constants::icase;

const std::tr1::regex pattern("http://[^\\\"\\>\\<]+?\\.(png|jpg|bmp)",fl);

std::tr1::smatch result;

std::string::const_iterator itS = strHtml.begin();

std::string::const_iterator itE = strHtml.end();

while(regex_search(itS,itE, result, pattern))//假设匹配成功

{

//m_clbRegex.AddString((CString)result[0].str().c_str());

m_clbRegex.AddString((CString)(string(result[0].first,result[0].second)).c_str());

itS=result[0].second;//新的位置開始匹配

}

[代码说明]

1. 创建正則表達式对象,有3中方法:

(1) 使用构造函数

std::regex_constants::syntax_option_type fl = std::regex_constants::icase; // 语法选项,能够设置使用哪种风格的正則表達式语法等.

std::wregex regExpress(regString, fl);

(2) 使用赋值运算符,缺点是不能指定语法选项,并且也比較低效.

std::wregex regExpress;

regExpress = regString;

(3) 使用assign方法.

std::wregex regExpress;

regExpress.assign(regString, fl);

构造正则对象的过称就是所谓的"编译".

2. regex_match() 和 regex_search()

regex_match()仅仅有在整个字符串匹配正則表達式时才返回 true, 而 regex_search()在子串匹配就返回 true.

3. 匹配结果对象 std::wsmatch.

熟悉Perl正則表達式的人都知道,匹配成功后能够用 $1 $2 ... $N 来获得子串的指, tr1 regex库把匹配结果保存在一个 std::wsmatch(UNICODE) / std::smatch(ANSI) 对象中.

std::wsmatch 是一个由若干个 std::wssub_match 对象构成的数组. 而 std::wssub_match 派生自 pair.

由std::wssub_match::first保存子串的起始位置指针(事实上说是迭代器比較准确一点).

由std::wssub_match::second保存子串的结束位置 +1 的指针(STL的通用原则,半开区间).

所以 [std::wssub_match::first,std::wssub_match::second) 就是子串的所有内容.

当然, std::wsmatch (match_result模版的提前定义类) 提供了一些简便的方法用于訪问子串:

(1) str(idx) 方法返回相应的子串的 std::string / std::wstring 对象. 仅仅是最经常使用的.

(2) position(idx) 方法返回相应子串的起始偏移量.(不是指针,是相对于首字节地址或者begin()的偏移量).

(3) length(idx) 返回子串的长度.

4. 替换子串.

前面说到 std::wssub_match::first / second 保存了子串的起始/结束位置,那么我们当然能够用这个指针(迭代器)来替换文本(见代码中的 "替换1").

或者用 std::regex_replace() 也能够达到目的(见代码中的"替换2").

几个经常使用的表达式:

"\\b1[35][0-9]\\d{8}|147\\d{8}|1[8][01236789]\\d{8}\\b";//手机号

"\\b0\\d{2,3}\\-?\\d{7,8}\b"; //座机

"\\b[1-9]\\d{5}(?:19|20)\\d{2}(?:0[1-9]|[1][012])(?#月)(?:0[1-9]|[12][0-9]|[3][01])(?#日)\\d{3}[\d|X|x]\\b"; //18位身份证

"\\b[1-9]\\d{7}(?:0[1-9]|[1][012])(?#月)(?:0[1-9]|[12][0-9]|[3][01])(?#日)\\d{3}\\b"; //15位身份证

"\\b(?:(?:2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(?:2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\b";  //ip4

"\\b(?:[a-zA-Z0-9_-])+@(?:[a-zA-Z0-9_-])+(?:\\.[a-zA-Z0-9_-]{2,3}){1,2}\\b"; //邮箱

时间: 2024-11-06 19:42:09

c++ 正則表達式的相关文章

javascript中的正則表達式

对文本数据进行操作是JavaScript中常见的任务.正則表達式通过同意程序猿指定字符串匹配的模式来简化诸如验证表单中输入是否具有正确格式之类的任务. 1.正則表達式标记: 字符 含义 举例 i 大写和小写不敏感 对于模式/http/i  "http" 和"HttP" 一样能够匹配 g 全局匹配.找出所有匹配字符串,而不不过找到第一个就返回. 经常使用于替换 m 多行匹配 2.正則表達式位置指示符:规定模式在它所匹配的字符串里的位置. 字符 含义 举例 ^ 开头 对

经验之谈—正則表達式实现图文混排

在项目中,我们常常须要发表情,以及常常须要将表情字符转换成表情.由于表情是一个图片.所以我们发给server的时候,实际上是发一段特殊的文字给server,然后转换成表情.以免浪费用户过多的流量. 那接下来.我们就来介绍一下,怎样使用正則表達式实现图文混排呢? 为了以后的代码的管理方便,我们抽取出两个类: NSString+Regular.h中.我们暴露两个方法出来: /** * 返回正則表達式匹配的第一个结果 * * @param pattern 正則表達式 * * @return 匹配的第一

JAVA学习第六十五课 — 正則表達式

正則表達式:主要应用于操作字符串.通过一些特定的符号来体现 举例: QQ号的校验 6~9位.0不得开头.必须是数字 String类中有matches方法 matches(String regex) 告知此字符串是否匹配给定的正則表達式. regex,就是给定的正則表達式 public static void checkQQ() { //第一位是数字1-9,第二位以后是0-9,除去第一位数剩下数字位数范围是5到8位 String regex = "[1-9][0-9]{5,8}";//正

HDU-1039-Easier Done Than Said?(Java &amp;amp;&amp;amp; 没用正則表達式是我的遗憾.....)

Easier Done Than Said? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9845    Accepted Submission(s): 4784 Problem Description Password security is a tricky thing. Users prefer simple password

正則表達式

一.概述 正則表達式是一种能够用于模式匹配和替换的强有力的工具.其作用例如以下: (1)測试字符串的某个模式.比如,能够对一个输入字符串进行測试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式.这称为数据有效性验证. (2)替换文本.能够在文档中使用一个正則表達式来标识特定文字,然后能够所有将其删除,或者替换为别的文字: (3)依据模式匹配从字符串中提取一个子字符串. 能够用来在文本或输入字段中查找特定文字. 二.匹配字符 字符 解释说明 \ 将下一字符标记为特殊字符.文本.反向引用或

js正則表達式语法

1. 正則表達式规则 1.1 普通字符 字母.数字.汉字.下划线.以及后边章节中没有特殊定义的标点符号,都是"普通字符".表达式中的普通字符,在匹配一个字符串的时候,匹配与之同样的一个字符. 举例1:表达式 "c",在匹配字符串 "abcde" 时,匹配结果是:成功:匹配到的内容是:"c":匹配到的位置是:開始于2,结束于3.(注:下标从0開始还是从1開始,因当前编程语言的不同而可能不同) 举例2:表达式 "bcd&

Java正則表達式入门

众所周知,在程序开发中,难免会遇到须要匹配.查找.替换.推断字符串的情况发生,而这些情况有时又比較复杂,假设用纯编码方式解决,往往会浪费程序猿的时间及精力.因此,学习及使用正則表達式,便成了解决这一矛盾的主要手段. 大 家都知道,正則表達式是一种能够用于模式匹配和替换的规范,一个正則表達式就是由普通的字符(比如字符a到z)以及特殊字符(元字符)组成的文字模式,它 用以描写叙述在查找文字主体时待匹配的一个或多个字符串.正則表達式作为一个模板,将某个字符模式与所搜索的字符串进行匹配.  自从jdk1

DOM笔记(十):JavaScript正則表達式

一.RegExp ECMAScript通过RegExp类型类支持正則表達式,语法和Perl类似: var exp = /pattern/flags; patternb部分是不论什么简单的或复杂的正則表達式:flags是每一个正則表達式所带的一个或者多个标志. 正則表達式的模式匹配支持三个标志: g:全局模式,即模式应用于整个字符串.而非在发现第一个匹配项时马上停止 i:不区分大写和小写模式 m:多行模式,即到达一行文本末尾是还会继续茶查找下一行中是否存在与模式匹配的项. 1.创建正則表達式 Ja

正則表達式常见例题

常见例题 例1:北美地区的电话号 编码方案:电话号码有一个3位数的区号和一位7位数的号码组成(这个7位数有分成  一个3位的局号和一个4位的路号.局号和路号之间使用连字符分隔) 每位电话号码能够是随意数字,可是区号和局号的第一位数字不能是0或1.实际书写号码是往往会把区号写在括号中面,或者将区号使用连字符和后面的局号连接起来.比如:(555)123-1234或555-123-1234,有时候在括号你里面会包括空格.比如:(555 )123-1234 文本: J.Doe:248-555-1234

shell脚本学习笔记 (正則表達式)

正則表達式一般有三个部分组成,他们各自是:字符类,数量限定符,位置限定符. 规定一些特殊语法表示字符类.数 量限定符和位置关系,然后用这些特殊语法和普通字符一起表示一个模式,这就是正則表達式(Regular Expression). 我们以一 个样例開始吧.假如给你一个文件,里面存放的是IP地址,可是有一些不是合格的.请你找出合格的IP地址.我想不知道正 则表达式的人一定会认为好陌生,我拿一个循环去实现,我之前也被问到过这个问题,也是想着拿循环来完毕.写出一个函 数来实现这个查找功能实在是不简单