哪些在C语言中巧用正则表明式,正则表明式声卡

在Java中的正则表达式使用的,依次读取文件中各行的字符串(字符串之间以空格分开),标准的C和C++都不支持正则表达式

图片 2

C++实践:正则表达式深入剖析声卡参数,正则表明式声卡

C++实行:正则表达式拆解分析声卡参数

在Java中的正则表明式使用的

//============================================================================

// Name : CppPro.cpp

// Author :

// Version :

// Copyright : Your copyright notice

// Description : Hello World in C++, Ansi-style

//============================================================================

#include

#include

#include

using namespace std;

/**

* 在构造函数中

*/

class Card {

public:

int getId() const {

return id;

}

private:

int id;

string name;

class Device {

int id;

};

};

string trim(string& str)

{

size_t first = str.find_first_not_of(‘ ‘);

if (first == string::npos)

return “”;

size_t last = str.find_last_not_of(‘ ‘);

return str.substr(first, (last-first+1));

}

/**

* 运转四个Loop选拔客户端命令

*/

int main() {

std::string id;

std::string name;

smatch sm; // 贮存string结果的器皿

std::string txt = ” 0 [PCH ]: HDA-Intel – HDA Intel PCH”;

std::string re1 = “( )”; // Any Single Character 1

std::string re2 = “(\\d+)”; // Integer Number 1

std::string re3 = “( )”; // Any Single Character 2

std::string re4 = “(\\[.*?\\])”; // Square Braces 1

std::string re5 = “(:)”; // Any Single Character 3

std::string re6 = “( )”; // Any Single Character 4

if (regex_search(txt, sm, regex(re1 + re2 + re3 + re4 + re5 + re6))) {

id = sm[2];

name = sm[4];

name = name.substr(1, name.length() – 2);

name = trim(name);

}

cout<< “name: ” << name << ” id: ” << id
<< endl;

}

运作结果:

name: PCH id: 0

C++试行:正则表明式解析声卡参数
在Java中的正则表明式使用的…

豆蔻梢头、问题叙述

见状我们商酌这方面包车型大巴事物,作点进献聊表各位高手对这么些版快的无私进献 😳 

 

若果客户熟练Linux下的sed、awk、grep或vi,那么对正则表明式这一概念料定不会不熟悉。由于它可以非常的大地简化管理字符串时的复杂度,由此今后以前在超级多Linux实用工具中赢得了运用。千万不要以为正则表明式只是Perl、Python、Bash等脚本语言的专利,作为C语言技士,客商相像能够在投机的次序中动用正则表明式。 

给定一文件,依次读取文件中各行的字符串(字符串之间以空格分开卡塔 尔(阿拉伯语:قطر‎。

业内的C和C++都不扶植正则表明式,但有点函数库能够扶助C/C++技士达成那风流倜傥效益,当中最资深的当数Philip Hazel的Perl-Compatible Regular Expression库,大多Linux发行版本都包蕴这一个函数库。 

举个例子:文件test.txt中好似下内容:

编写翻译正则表达式 

first  second  third  forth  (第一行)

为了进步功用,在将二个字符串与正则表明式举行比较前边,首先要用regcomp()函数对它进行编写翻译,将其转变为regex_t结构: 

fifth  sixth seventh   (第二上)

int regcomp(regex_t *preg, const char *regex, int cflags);
 

… (其他行)

参数regex是二个字符串,它表示就要被编写翻译的正则说明式;参数preg指向叁个宣称为regex_t的数据结构,用来保存编写翻译结果;参数cflags决定了正则表明式该如何被拍卖的细节。 

则读取的内容逐条为:   first  second  third  forth   fifth  sixth
seventh

生机勃勃旦函数regcomp()实行成功,而且编写翻译结果被科学填写到preg中后,函数将重返0,任何其余的归来结果都意味着有某种错误发生。 

 

相称正则表明式 

二、解题步骤

假定用regcomp()函数成功地编写翻译了正则表达式,接下去就可以调用regexec()函数达成形式相称: 

 

int regexec(const  regex_t  *preg,  const  char *string, size_t nmatch,regmatch_t pmatch[], int eflags);
typedef struct {
  regoff_t rm_so;
  regoff_t rm_eo;
} regmatch_t;
 

(1卡塔 尔(英语:State of Qatar)首先读取文件各行

参数preg指向编译后的正则表明式,参数string是即将举行相称的字符串,而参数nmatch和pmatch则用来把匹配结果重回给调用程序,最终二个参数eflags决定了十一分的内部景况。 

(2卡塔 尔(阿拉伯语:قطر‎然后针对每行依次读取各种字符串

在调用函数regexec()进行形式相称的历程中,大概在字符串string中会有多处与给定的正则表明式相相配,参数pmatch正是用来保存这一个相称岗位的,而参数nmatch则告知函数regexec()最多能够把多少个门当户对结果填充到pmatch数组中。当regexec()函数成功重临时,从string+pmatch[0].rm_so到string+pmatch[0].rm_eo是第三个门户大致的字符串,而从string+pmatch[1].rm_so到string+pmatch[1].rm_eo,则是第2个卓绝的字符串,由此及彼。 

(3卡塔 尔(阿拉伯语:قطر‎最后将读取的字符串依次存入内存中

获释正则表达式 

 

随便如何时候,当不再须要已经编译过的正则表达式时,都应该调用函数regfree()将其释放,避防产生内部存款和储蓄器泄漏。 

三、编制程序实现

void regfree(regex_t *preg);
 

 

函数regfree()不会重临任何结果,它仅收受叁个指向regex_t数据类型的指针,这是事先调用regcomp()函数所获得的编写翻译结果。 

1、C语言达成

朝气蓬勃经在前后相继中针对同二个regex_t结构调用了多次regcomp()函数,POSIX规范并从未鲜明是不是每一回都一定要调用regfree()函数实行自由,但建议每趟调用regcomp()函数对正则表达式进行编写翻译后都调用一回regfree()函数,以尽早获释占用的积攒空间。 

在C语言中,有个函数:strtok() 用于分割字符串,其原型如下:

告知错误新闻 

[cpp] view plaincopyprint?
#include <string.h>  
char* strtok(char str[], const char* delim); 

只要调用函数regcomp()或regexec()获得的是四个非0的再次来到值,则表明在对正则表明式的管理进度中现身了某种错误,那时得以由此调用函数regerror()获得详细的错误音讯。 

#include <string.h>
char* strtok(char str[], const char* delim);
说明:

size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
 

I、参数:str为待分割的字符串;delim为分隔符字符串。

参数errcode是根源函数regcomp()或regexec()的错误代码,而参数preg则是由函数regcomp()获得的编写翻译结果,其指标是把格式化音信所必需的上下文提须求regerror()函数。在实践函数regerror()时,将如约参数errbuf_size指明的最大字节数,在errbuf缓冲区中填入格式化后的错误新闻,相同的时间再次来到错误音讯的长度。 

II、用法:该函数的应用比较好奇,若在str字符串中窥见参数delim中的分割字符串之字符时,则会将该字符改善为‘\0’字符(字符串停止符卡塔 尔(阿拉伯语:قطر‎。在第叁次调用时,strtok()必需付与参数str字符串,下一次调用时则须将str设置成NULL。每回调用成功则赶回指向被细分出大器晚成部分的指针。

行使正则表明式 

例子:

末尾交给一个现实的实例,介绍如何在C语言程序中拍卖正则表明式。 

[cpp]
#include <stdio.h>  
#include <string.h>  
int main() 

    char s[] =”ab|cdef;ghi|jkl”; 
    char* delim = “|;”; 
    char* tmp; 
    tmp = strtok(s, delim); 
    while(tmp != NULL) 
    {    
        printf(“%s\n”,tmp); 
        tmp = strtok(NULL, delim);   
    } 
 
    return 0; 

#include <stdio.h>;
#include <sys/types.h>;
#include <regex.h>;

#include <stdio.h>
#include <string.h>
int main()
{
 char s[] =”ab|cdef;ghi|jkl”;
 char* delim = “|;”;
 char* tmp;
 tmp = strtok(s, delim);
 while(tmp != NULL)
 { 
  printf(“%s\n”,tmp);
  tmp = strtok(NULL, delim); 
 }

/* 取子串的函数 */
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(&reg, pattern, cflags);
  if (z != 0){
    regerror(z, &reg, 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(&reg, lbuf, nmatch, pm, 0);
    if (z == REG_NOMATCH) continue;
    else if (z != 0) {
      regerror(z, &reg, 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(&reg);
  return 0;
}
 

 return 0;
}
输出:

上述顺序担负从命令行获取正则表明式,然后将其应用于从正式输入得到的每行数据,并打字与印刷出同盟结果。推行下边包车型地铁一声令下能够编写翻译并实施该程序: 

 图片 1
 

#  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(&reg, lbuf, nmatch, pm, 0);
  $0=’regexec’
 

 

小结 

 

对那个要求张开复杂数据管理的顺序来讲,正则表明式无疑是叁个老大实惠的工具。本文入眼在于论述怎么着在C语言中接收正则表达式来简化字符串管理,以便在数额处理方面能够得到与Perl语言形似的八面见光

上面给出读文件各行中的字符串,并将其保存于内部存款和储蓄器中。设文件名称叫:test.txt,其情节如下:

 

图片 2

相应的前后相继为:

[cpp] 
#include <stdio.h>  
#include <string.h>  
 
/*
@in, str: 待分割的字符串
@in, delim: 分隔符字符串
@in_out, dest:
保存分割后的每一个字符串,设为char**的引用,即表示可修正其值
@out, pCount: 记录风姿浪漫行中分割所得字符串的个数
*/ 
void split(char* str, char* delim, char** &dest, int* pCount) 

    char* tmp; 
    *pCount=0; 
    if(NULL ==  str || 0 == strlen(str)) return ; 
    if(NULL == delim || 0 == strlen(delim)) return ; 
 
    tmp = strtok(str, delim); 
    while(tmp != NULL) 
    {    
        for(int j =0; tmp[j]!=’\0′;j++) 
        { 
            if(tmp[j]==’\n’)break; //到达行末  
            (*dest)[j] = tmp[j]; 
        } 
        (*dest)[j]=’\0′; 
        dest++;  
        (*pCount)++; 
 
        tmp = strtok(NULL, delim); 
    } 

int main() 

 
    FILE* fp; 
    char lineBuf[129]; 
    char* delim = ” “;  //分隔符为:空格  
    int num = 0;    //文件中总的字符串个数  
    int count = 0;  //大器晚成行中的字符串个数  
    int i; 
 
    /*提请内部存款和储蓄器用于寄存字符串*/ 
    char** dest  = new char*[128]; 
    for( i = 0; i < 128; i++) 
    { 
        dest[i] = new char[64]; 
    } 
 
    char** tmpDest = dest; 
    if(fp=fopen(“test.txt”, “r”)) 
    {    
        while(fgets(lineBuf, 128, fp) != NULL) 
        { 
            split(lineBuf, delim, tmpDest, &count); 
            num  = num + count; 
        } 
    } 
    fclose(fp); 
 
    for(i= 0; i < num; i++) 
    { 
        printf(“%s\n”,dest[i]); 
    } 
 
    /*获释内部存款和储蓄器*/ 
    for(i = 0; i<128;i++) 
    { 
        delete []dest[i]; 
    } 
    delete[]dest; 
 
    return 0; 

#include <stdio.h>
#include <string.h>

/*
@in, str: 待分割的字符串
@in, delim: 分隔符字符串
@in_out, dest:
保存分割后的各样字符串,设为char**的援引,即意味着可修改其值
@out, pCount: 记录黄金时代行中分割所得字符串的个数
*/
void split(char* str, char* delim, char** &dest, int* pCount)
{
 char* tmp;
 *pCount=0;
 if(NULL ==  str || 0 == strlen(str)) return ;
 if(NULL == delim || 0 == strlen(delim)) return ;

 tmp = strtok(str, delim);
 while(tmp != NULL)
 { 
  for(int j =0; tmp[j]!=’\0′;j++)
  {
   if(tmp[j]==’\n’)break; //达到行末
   (*dest)[j] = tmp[j];
  }
  (*dest)[j]=’\0′;
  dest++; 
  (*pCount)++;

  tmp = strtok(NULL, delim);
 }
}
int main()
{

 FILE* fp;
 char lineBuf[129];
 char* delim = ” “; //分隔符为:空格
 int num = 0; //文件中总的字符串个数
 int count = 0; //后生可畏行中的字符串个数
 int i;

 /*提请内部存储器用于存放字符串*/
 char** dest  = new char*[128];
 for( i = 0; i < 128; i++)
 {
  dest[i] = new char[64];
 }

 char** tmpDest = dest;
 if(fp=fopen(“test.txt”, “r”))
 { 
  while(fgets(lineBuf, 128, fp) != NULL)
  {
   split(lineBuf, delim, tmpDest, &count);
   num  = num + count;
  }
 }
 fclose(fp);

 for(i= 0; i < num; i++)
 {
  printf(“%s\n”,dest[i]);
 }

 /*放出内部存款和储蓄器*/
 for(i = 0; i<128;i++)
 {
  delete []dest[i];
 }
 delete[]dest;

 return 0;
}

 

2、C++语言落成

C++中没有完结split成效的函数,上面用C++
STL中的一些函数模拟实现split功效。

[cpp] 
#include <iostream>  
#include <string>  
#include <vector>  
#include <fstream>  
using namespace std; 
 
/*
@in, src: 待分割的字符串
@in, delim: 分隔符字符串
@in_out, dest: 保存分割后的种种字符串
*/ 
void split(const string& src, const string& delim, vector<string>&
dest) 

    string str = src; 
    string::size_type start = 0, index; 
    string substr; 
 
    index = str.find_first_of(delim, start);   
//在str中探求(开端:start) delim的放肆字符的率先次面世的任务  
    while(index != string::npos) 
    { 
        substr = str.substr(start, index-start); 
        dest.push_back(substr); 
        start = str.find_first_not_of(delim, index);   
//在str中检索(初始:index) 第三个不归属delim的字符现身的职位  
        if(start == string::npos) return; 
 
        index = str.find_first_of(delim, start); 
    } 

 
 
int main() 

    ifstream infile(“test.txt”, ios::in); 
    vector<string> results; 
    string word; 
    string delim(” “); 
    string textline; 
    if(infile.good()) 
    { 
        while(!infile.fail()) 
        { 
            getline(infile, textline); 
            split(textline, delim, results); 
        } 
    } 
    infile.close(); 
 
    vector<string>::iterator iter = results.begin(); 
    while(iter != results.end()) 
    { 
        cout<<*iter++<<endl; 
    } 
 
    return 0; 

#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;

/*
@in, src: 待分割的字符串
@in, delim: 分隔符字符串
@in_out, dest: 保存分割后的每一个字符串
*/
void split(const string& src, const string& delim, vector<string>&
dest)
{
 string str = src;
 string::size_type start = 0, index;
 string substr;

 index = str.find_first_of(delim, start); //在str中搜索(起初:start)
delim的即兴字符的首先次面世的职分
 while(index != string::npos)
 {
  substr = str.substr(start, index-start);
  dest.push_back(substr);
  start = str.find_first_not_of(delim,
index); //在str中搜寻(起始:index) 第贰个不归属delim的字符现身的职位
  if(start == string::npos) return;

  index = str.find_first_of(delim, start);
 }
}

int main()
{
 ifstream infile(“test.txt”, ios::in);
 vector<string> results;
 string word;
 string delim(” “);
 string textline;
 if(infile.good())
 {
  while(!infile.fail())
  {
   getline(infile, textline);
   split(textline, delim, results);
  }
 }
 infile.close();

 vector<string>::iterator iter = results.begin();
 while(iter != results.end())
 {
  cout<<*iter++<<endl;
 }

 return 0;
}

 

3、Python语言的贯彻

在Python中有非常的函数split()对字符串实行私分,完成较为轻便

[python] 
myfile = open(‘test.txt’, ‘r’) 
allWords = [] 
line = myfile.readline() 
while line: 
    list = line.split(‘ ‘) 
    for word in list: 
        if word[-1]==’\n’: 
            allWords.append(word[:-1])  #去掉行末的’\n’  
        else: 
            allWords.append(word) 
    line = myfile.readline() 
myfile.close()   
print allWords 

myfile = open(‘test.txt’, ‘r’)
allWords = []
line = myfile.readline()
while line:
 list = line.split(‘ ‘)
 for word in list:
  if word[-1]==’\n’:
   allWords.append(word[:-1]) #去掉行末的’\n’
  else:
   allWords.append(word)
 line = myfile.readline()
myfile.close() 
print allWords

给定一文件,依次读取文件中各行的字符串(字符串之间以空格分开卡塔 尔(英语:State of Qatar)。
比方:文件test.txt中宛如下内容: first second third…