精华内容
参与话题
问答
  • regex

    2013-03-07 20:07:30
    标准的C和C++都不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这一功能,其中最著名的当数Philip Hazel的Perl-Compatible Regular Expression库,许多Linux发行版本都带有这个函数库。...
    标准的C和C++都不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这一功能,其中最著名的当数Philip Hazel的Perl-Compatible Regular Expression库,许多Linux发行版本都带有这个函数库。

    C语言处理正则表达式常用的函数有regcomp()、regexec()、regfree()和regerror(),一般分为三个步骤,如下所示:

    C语言中使用正则表达式一般分为三步:
    1. 编译正则表达式 regcomp()
    2. 匹配正则表达式 regexec()
    3. 释放正则表达式 regfree()


    下边是对三个函数的详细解释

    1、int regcomp (regex_t *compiled, const char *pattern, int cflags)
    这个函数把指定的正则表达式pattern编译成一种特定的数据格式compiled,这样可以使匹配更有效。函数regexec 会使用这个数据在目标文本串中进行模式匹配。执行成功返回0。  

    参数说明:
    ①regex_t 是一个结构体数据类型,用来存放编译后的正则表达式,它的成员re_nsub 用来存储正则表达式中的子正则表达式的个数,子正则表达式就是用圆括号包起来的部分表达式。
    ②pattern 是指向我们写好的正则表达式的指针。
    ③cflags 有如下4个值或者是它们或运算(|)后的值:
    REG_EXTENDED 以功能更加强大的扩展正则表达式的方式进行匹配。
    REG_ICASE 匹配字母时忽略大小写。
    REG_NOSUB 不用存储匹配后的结果。
    REG_NEWLINE 识别换行符,这样'$'就可以从行尾开始匹配,'^'就可以从行的开头开始匹配。

    2. int regexec (regex_t *compiled, char *string, size_t nmatch, regmatch_t matchptr [], int eflags)
    当我们编译好正则表达式后,就可以用regexec 匹配我们的目标文本串了,如果在编译正则表达式的时候没有指定cflags的参数为REG_NEWLINE,则默认情况下是忽略换行符的,也就是把整个文本串当作一个字符串处理。执行成功返回0。
    regmatch_t 是一个结构体数据类型,在regex.h中定义:             
    typedef struct
    {
       regoff_t rm_so;
       regoff_t rm_eo;
    } regmatch_t;
    成员rm_so 存放匹配文本串在目标串中的开始位置,rm_eo 存放结束位置。通常我们以数组的形式定义一组这样的结构。因为往往我们的正则表达式中还包含子正则表达式。数组0单元存放主正则表达式位置,后边的单元依次存放子正则表达式位置。

    参数说明:
    ①compiled 是已经用regcomp函数编译好的正则表达式。
    ②string 是目标文本串。
    ③nmatch 是regmatch_t结构体数组的长度。
    ④matchptr regmatch_t类型的结构体数组,存放匹配文本串的位置信息。
    ⑤eflags 有两个值
    REG_NOTBOL 按我的理解是如果指定了这个值,那么'^'就不会从我们的目标串开始匹配。总之我到现在还不是很明白这个参数的意义;
    REG_NOTEOL 和上边那个作用差不多,不过这个指定结束end of line。

    3. void regfree (regex_t *compiled)
    当我们使用完编译好的正则表达式后,或者要重新编译其他正则表达式的时候,我们可以用这个函数清空compiled指向的regex_t结构体的内容,请记住,如果是重新编译的话,一定要先清空regex_t结构体

    4. size_t regerror (int errcode, regex_t *compiled, char *buffer, size_t length)
    当执行regcomp 或者regexec 产生错误的时候,就可以调用这个函数而返回一个包含错误信息的字符串。

    参数说明:
    ①errcode 是由regcomp 和 regexec 函数返回的错误代号。
    ②compiled 是已经用regcomp函数编译好的正则表达式,这个值可以为NULL。
    ③buffer 指向用来存放错误信息的字符串的内存空间。
    ④length 指明buffer的长度,如果这个错误信息的长度大于这个值,则regerror 函数会自动截断超出的字符串,但他仍然会返回完整的字符串的长度。所以我们可以用如下的方法先得到错误字符串的长度。

    size_t length = regerror (errcode, compiled, NULL, 0);

    下边是一个匹配Email例子,按照上面的三步就可以。


    下面的程序负责从命令行获取正则表达式,然后将其运用于从标准输入得到的每行数据,并打印出匹配结果。
    #include <stdio.h>
    #include <sys/types.h>
    #include <regex.h>

    /* 取子串的函数 */
    static char* substr(const char*str,
    unsigned start, unsigned end)
    {
      unsigned n = end - start;
      static char stbuf[256];
      strncpy(stbuf, str + start, n);
      stbuf[n] = 0;
      return stbuf;
    }

    /* 主程序 */
    int main(int argc, char** argv)
    {
      char * pattern;
      int x, z, lno = 0, cflags = 0;
      char ebuf[128], lbuf[256];
      regex_t reg;
      regmatch_t pm[10];
      const size_t nmatch = 10;
      /* 编译正则表达式*/
      pattern = argv[1];
      z = regcomp(?, pattern, cflags);
      if (z != 0){
        regerror(z, ?, ebuf, sizeof(ebuf));
        fprintf(stderr, "%s: pattern '%s' \n",ebuf, pattern);
        return 1;
      }
      /* 逐行处理输入的数据 */
      while(fgets(lbuf, sizeof(lbuf), stdin))
      {
        ++lno;
        if ((z = strlen(lbuf)) > 0 && lbuf[z-1] == '\n')
        lbuf[z - 1] = 0;
        /* 对每一行应用正则表达式进行匹配 */
        z = regexec(?, lbuf, nmatch, pm, 0);
        if (z == REG_NOMATCH) continue;
        else if (z != 0) {
          regerror(z, ?, ebuf, sizeof(ebuf));
          fprintf(stderr, "%s: regcom('%s')\n", ebuf, lbuf);
          return 2;
        }
        /* 输出处理结果 */
        for (x = 0; x < nmatch && pm[x].rm_so != -1; ++ x)
        {
          if (!x) printf("%04d: %s\n", lno, lbuf);
          printf(" $%d='%s'\n", x, substr(lbuf, pm[x].rm_so, pm[x].rm_eo));
        }
      }
      /* 释放正则表达式 */
      regfree(?);
      return 0;
    }

    执行下面的命令可以编译并执行该程序:
    # gcc regexp.c -o regexp
    # ./regexp 'regex[a-z]*' < regexp.c
    0003: #include <regex.h>
    $0='regex'
    0027: regex_t reg;
    $0='regex'
    0054: z = regexec(?, lbuf, nmatch, pm, 0);
    $0='regexec'



    小结:对那些需要进行复杂数据处理的程序来说,正则表达式无疑是一个非常有用的工具。本文重点在于阐述如何在C语言中利用正则表达式来简化字符串处理,以便在数据处理方面能够获得与Perl语言类似的灵活性。
    展开全文
  • Regex

    2016-05-04 09:54:00
    #include "boost/regex.hpp" //完全匹配 void boostregex_match(void); //部分数据可以匹配 void boostregex_search(void); //替换 void boostregex_replace(void); //关于重复和贪婪 void Test1(void)
    #include <iostream>
    #include <cassert>
    #include <string>
    #include "boost/regex.hpp"
    
    //完全匹配
    void boostregex_match(void);
    
    //部分数据可以匹配
    void boostregex_search(void);
    
    //替换
    void boostregex_replace(void);
    
    //关于重复和贪婪
    void Test1(void);
    
    //regex_iterator
    void Test2(void);
    
    //regex_token_iterator 
    void Test3(void);
    
    int main() 
    { 
    	//boostregex_search();
    	//boostregex_replace();
    	//Test1();
    	//Test2();
    	Test3();
    	return 0;
    }
    
    void boostregex_match(void)
    {
    	// 3 digits, a word, any character, 2 digits or "N/A",   // a space, then the first word again 
    	//用于表示"3个数字, 一个单词, 任意字符, 2个数字或字符串"N/A," 一个空格, 然后重复第一个单词.":
    	boost::regex reg("\\d{3}([a-zA-Z]+).(\\d{2}|N/A)\\s\\1");
    	std::string correct = "123Hello N/A Hello";
    	std::string incorrect = "123Hello 12 hello";
    	assert(boost::regex_match(correct, reg) == true);
    	assert(boost::regex_match(incorrect, reg) == false);
    	return;
    }
    
    //部分数据可以匹配
    void boostregex_search(void)
    {
    	// "new" and "delete" 出现的次数是否一样? 
    	boost::regex reg("(new)|(delete)"); 
    	boost::smatch m;  
    	std::string s=    "Calls to new must be followed by delete. \     Calling simply new results in a leak!";  
    	int new_counter=0; 
    	int delete_counter=0; 
    	std::string::const_iterator it=s.begin();  
    	std::string::const_iterator end=s.end();  
    	while (boost::regex_search(it,end,m,reg)) 
    	{    // 是 new 还是 delete?  
    		m[1].matched ? ++new_counter : ++delete_counter; 
    		it=m[0].second; 
    	} 
    	if (new_counter!=delete_counter) 
    		std::cout << "Leak detected!\n";  
    	else    
    		std::cout << "Seems ok...\n";
    	return;
    	/*
    	Leak detected!
    请按任意键继续. . .
    	*/
    }
    
    //替换
    void boostregex_replace(void)
    {
    	boost::regex reg("(Colo)(u)(r)", 
    	boost::regex::icase | boost::regex::perl);  
    	std::string s = "Colour, colours, color, colourize";  
    	s = boost::regex_replace(s, reg, "$1$3");  
    	std::cout << s;
    	return;
    	/*
    	Color, colors, color, colorize请按任意键继续. . .
    	*/
    }
    
    //关于重复和贪婪
    void Test1(void)
    {
    	boost::regex reg("(.*)(\\d{2})");  
    	boost::cmatch m;  
    	const char* text = "Note that I'm 31 years old, not 32.";  
    	if (boost::regex_search(text, m, reg)) {
    		if (m[1].matched)      
    			std::cout << "(.*) matched: " << m[1].str() << '\n';   
    		if (m[2].matched)      
    			std::cout << "Found the age: " << m[2] << '\n'; }
    	return;
    	/*
    	(.*) matched: Note that I'm 31 years old, not
    Found the age: 32
    请按任意键继续. . .
    	*/
    }
    
    
    class regex_callback 
    { 
    	int sum_; 
    public: 
    	regex_callback() : sum_(0) {}  
    	template <typename T> void operator()(const T& what) 
    	{
    		sum_ += atoi(what[1].str().c_str()); 
    	}  
    	int sum() const { return sum_; }
    
    };
    
    //regex_iterator
    void Test2(void)
    {
    	boost::regex reg("(\\d+),?");  
    	std::string s = "1,1,2,3,5,8,13,21";  
    	boost::sregex_iterator it(s.begin(), s.end(), reg);  
    	boost::sregex_iterator end;  regex_callback c;  
    	int sum = for_each(it, end, c).sum();
    	return;
    }
    
    //regex_token_iterator 
    void Test3(void)
    {
    	boost::regex reg("/");  
    	std::string s = "Split/Values/Separated/By/Slashes,"; 
    	std::vector<std::string> vec;  
    	boost::sregex_token_iterator it(s.begin(), s.end(), reg, -1);  
    	boost::sregex_token_iterator end;  
    	while (it != end)    
    		vec.push_back(*it++); 
    
    	assert(vec.size() == std::count(s.begin(), s.end(), '/') + 1);  
    	assert(vec[0] == "Split");
    	return;
    }

    展开全文
  • <p>Note that the fancy-regex implementation doesn't compile yet, but I thought it would be useful to get this reviewed earlier rather than later. <p>I haven't ported over the regex rewriting ...
  • C++正则表达式(regex_match、regex_search与regex_replace)

    万次阅读 多人点赞 2018-02-10 21:39:56
    正则表达式是在字符串处理中常用和重要的工具,主要用于字符串的匹配。

    前言

    正则表达式是在字符串处理中常用和重要的工具,主要用于字符串的匹配。在C#中正则表达式的使用非常方便,但到了C++中让我有点懵逼了,花了些时间查阅了很多资料,下面主要会写到C++中正则表达式常用到的三个方法(全文匹配、搜索和替换)的作用以及区别。
    本篇博客不涉及正则表达式语法的基本内容,如果你对正则表达式不了解,可以访问这个链接获得帮助。

    1 转义字符

    在讲具体方法之前,我们先了解下C++中使用正则表达式需要注意的一个问题:转义字符

    cout << regex_match("123", regex("\d+")) << endl;	//结果为0,需要转义字符'\'
    cout << regex_match("123", regex("\\d+")) << endl;	//结果为1,完全匹配
    
    • \d:匹配一个数字字符;
    • + :匹配一次或多次;

    C++中必须要对表达式中的’'进行转义,为什么?

    2 regex_match

    2.1 基本概念

    match是全文匹配,即要求整个字符串符合匹配规则。

    cout << regex_match("123", regex("\\d")) << endl;		//结果为0
    cout << regex_match("123", regex("\\d+")) << endl;		//结果为1
    

    上述方法返回值为bool值,主要用于if条件表达式中。

    2.2 匹配结果

    更多的时候我们希望能够获得匹配结果(字符串),对结果进行操作。这时就需要对匹配结果进行存储,共有两种存储方式。

    match_results<string::const_iterator> result;
    smatch result;			//推荐
    

    第二种方式使用起来更简洁、方便,推荐使用。

    2.3 实例

    下面看一个match方法匹配的实例,看看实际应用:

    string str = "Hello_2018";
    smatch result;
    regex pattern("(.{5})_(\\d{4})");	//匹配5个任意单字符 + 下划线 + 4个数字
    
    if (regex_match(str, result, pattern))
    {
    	cout << result[0] << endl;		//完整匹配结果,Hello_2018
    	cout << result[1] << endl;		//第一组匹配的数据,Hello
    	cout << result[2] << endl;		//第二组匹配的数据,2018
    	cout<<"结果显示形式2"<<endl;
    	cout<< result.str() << endl;	//完整结果,Hello_2018
    	cout<< result.str(1) << endl;	//第一组匹配的数据,Hello
    	cout << result.str(2) << endl;	//第二组匹配的数据,2018
    }
    
    //遍历结果
    for (int i = 0; i < result.size(); ++i)
    {
    	cout << result[i] << endl;
    }
    

    result[]与result.str()这两种方式能够获得相同的值,我更喜欢用数组形式的。
    在匹配规则中,以括号()的方式来划分组别,实例中的规则共有两个括号,所以共有两组数据。

    3 regex_search

    3.1 基本概念

    search是搜索匹配,即搜索字符串中存在符合规则的子字符串。
    match与search一比较便知:

    cout << regex_match("123", regex("\\d")) << endl;		//结果为0
    cout << regex_search("123", regex("\\d")) << endl;		//结果为1
    

    3.2 实例

    直接看例子:

    string str = "Hello 2018, Bye 2017";
    smatch result;
    regex pattern("\\d{4}");	//匹配四个数字
    
    //迭代器声明
    string::const_iterator iterStart = str.begin();
    string::const_iterator iterEnd = str.end();
    string temp;
    while (regex_search(iterStart, iterEnd, result, pattern))
    {
    	temp = result[0];
    	cout << temp << " ";
    	iterStart = result[0].second;	//更新搜索起始位置,搜索剩下的字符串
    }
    
    输出结果:2018 2017
    

    只需要利用迭代器就可以很轻松的访问到所有匹配的结果值。

    4 regex_replace

    4.1 基本概念

    replace是替换匹配,即可以将符合匹配规则的子字符串替换为其他字符串。

    string str = "Hello_2018!";
    regex pattern("Hello");	
    cout << regex_replace(str, pattern, "") << endl;	//输出:_2018,将Hello替换为""
    cout << regex_replace(str, pattern, "Hi") << endl;	//输出:Hi_2018,将Hello替换为Hi
    

    4.2 扩展

    除了直接替换以外,还有可以用来调整字符串内容(缩短、顺序等)。

    string str = "Hello_2018!";	
    regex pattern2("(.{3})(.{2})_(\\d{4})");				//匹配3个任意字符+2个任意字符+下划线+4个数字
    cout << regex_replace(str, pattern2, "$1$3") << endl;	//输出:Hel2018,将字符串替换为第一个和第三个表达式匹配的内容
    cout << regex_replace(str, pattern2, "$1$3$2") << endl;	//输出:Hel2018lo,交换位置顺序
    

    $n用于表示第n组匹配数据(组这个概念在文章前面部分提到过),所以我们可以利用这种方式来将字符串的内容进行调整。

    5 匹配忽略大小写

    有时我们希望能够匹配的时候忽略大小写,这时候就要用到Regex的语法选项了。

    cout << regex_match("aaaAAA", regex("a*", regex::icase)) << endl;	//结果为1
    cout << regex_match("aaaAAA", regex("a*")) << endl;					//结果为0
    

    regex::icase:匹配时忽略大小写。

    6 帮助网站

    附上两个写正则表达式常用到的网站

    展开全文
  • use regex::{Regex}; fn main() { simple_match_1(); simple_match_2(); } /// This example working on regex101: https://regex101.com/r/WJgwJ5/1 #[test] fn simple_match_1() { let regex_str = "...
  • Java中关于Regex的问题

    2017-06-14 09:42:56
    Exception in thread "main" java.util.regex.PatternSyntaxException: Unexpected internal error near index 1 \  ^  at java.util.regex.Pattern.error(Pattern.java:1955)  at java.util.regex.Pattern....
  • regex.h regex.cpp

    2018-01-19 18:25:12
    linux下的C语言正则表达式头文件和源文件: regex.h regex.cpp
  • RegEx Test

    热门讨论 2007-09-16 16:24:07
    RegEx Test 测试正则表达式。
  • However, an additional motivation to these changes was to permit users of <code>regex</code> to shrink its dependency tree, should they wish to give up runtime performance in exchange. While this may...
  • <p>I wrote this <code>regex</code> for checking the input number from my form: <pre><code>if (!preg_match("/^0\d{10}+|^9\d{9}+/",$_POST['number'])){ echo "Error"; }else{ echo "Ok"; } </code></pre> ...
  • Regex-2.7 for Windows 这个不用我说了吧,大家都知道,项目地址是: http://gnuwin32.sourceforge.net/packages/regex.htm 下载后的库如下图所示: ![图片说明]...
  • <pre><code>$regex = new MongoDB\BSON\Regex ( '^Al'); $cursor = $collection->find(array('name' => $regex)); //iterate through the cursor </code></pre> <p>then ...
  • 在用c语言写爬虫(入坑),想用正则表达式来判断url结果发现复杂的判断(在其他正则表达式测试工具可以正常判断出来)没法判断出来,换成简单的测试了下(代码如下匹配是简单的)可以匹配...还是说这是regex.h的问题==
  • <div><p>When I try to build regex_macros I got error: <pre><code> $ cargo build --release --verbose Fresh libc v0.2.20 Fresh void v1.0.2 Fresh utf8-ranges v1.0.0 Fresh regex-syntax v0.4.0 (file://...
  • ld: 0711-317 ERROR: Undefined symbol: .boost::re_detail_106400::perl_matcher*,std::allocator*> >,boost::regex_traits,boost::cpp_regex_traits<char> > >::find() ld: 0711-345 Use the -bloadmap or -...
  • regex判断数字

    千次阅读 2006-08-18 22:17:00
    public class Test { public static void main(String[] args) { String a = "-1"; Pattern p = Pattern.compile("[0-9]*|-[0-9]*"); Matcher m = p.matcher(a); boolean b = m.m
    public class Test {
        public static void main(String[] args) {
            String a = "-1";
             Pattern p = Pattern.compile("[0-9]*|-[0-9]*");
             Matcher m = p.matcher(a);
             boolean b = m.matches();
             System.out.println(b);
        }
    }
    判断是否是多个整数或负数
    展开全文
  • regex 正则软件

    2011-10-08 08:26:23
    regex 正则软件regex 正则软件regex 正则软件regex 正则软件regex 正则软件 让你很好的上手测试正则表达式

空空如也

1 2 3 4 5 ... 20
收藏数 37,043
精华内容 14,817
关键字:

regex