C/C++中使用正则表达式判断输入是否为16进制

  识别16进制的内容使用的表达式为:0[xX][[0-9a-fA-F]]+,识别10进制的内容使用的表达式为:"^[0-9]*$"
  在C++中使用正则表达式需要引入#include <regex>头文件,模式匹配使用regex_match函数。C中使用正则表达式需要引入#include <regex.h>头文件,模式匹配使用regcomp函数。

0. C++ 11中function template std::regex_match:
C-strings (1)
template <class charT, class traits>
  bool regex_match (const charT* s, const basic_regex<charT,traits>& rgx,
          regex_constants::match_flag_type flags = regex_constants::match_default);

strings (2)
template <class ST, class SA, char charT, class traits>
  bool regex_match (const basic_string<charT,ST,SA>& s,
          const basic_regex<charT,traits>& rgx,
          regex_constants::match_flag_type flags = regex_constants::match_default);

ranges (3)
template <class BidirectionalIterator, class charT, class traits>
  bool regex_match (BidirectionalIterator first, BidirectionalIterator last,
          const basic_regex<charT,traits>& rgx,
          regex_constants::match_flag_type flags = regex_constants::match_default);

with match_results (4,5,6)
template <class charT, class Alloc, class traits>
  bool regex_match (const charT* s, match_results<const charT*, Alloc>& m,
          const basic_regex<charT,traits>& rgx,
          regex_constants::match_flag_type flags = regex_constants::match_default);
template <class ST, class SA, class Alloc, class charT, class traits>
  bool regex_match (const basic_string<charT,ST,SA>& s,
          match_results<typename basic_string<charT,ST,SA>::const_iterator,Alloc>& m,
          const basic_regex<charT,traits>& rgx,
          regex_constants::match_flag_type flags = regex_constants::match_default);
template <class BidirectionalIterator, class Alloc, class charT, class traits>
  bool regex_match (BidirectionalIterator first, BidirectionalIterator last,
          match_results<BidirectionalIterator, Alloc>& m,
          const basic_regex<charT,traits>& rgx,
          regex_constants::match_flag_type flags = regex_constants::match_default);
1. 使用:
// 判断输入是否为16进制
string pattern = "0[xX][0-9a-fA-F]+";
regex re(pattern);
const string arg1 = "0x10";
if (!regex_match(arg1, re))
{
    cout << "reg not match" << endl;
}

// 判断输入是否为10进制
string pattern2 = "^[0-9]*$";
regex reg(pattern2);
const string arg2 = "10";
if (!regex_match(arg2, reg))
{
   cout << "reg not match" << endl;
}
2. 程序示例:

  编写一个完整的程序,正确的识别 16进制和 10进制数字,并返回两个数字相加的结果。假设有两个输入,每个输入字符串长度不超过10,合法输入为16 进制和10 进制表示。
代码如下:

#include <iostream>
#include <regex>
#include <string>
using namespace std;

int tolower(int c)
{
    if (c >= 'A' && c <= 'Z')
        return c + 'a' - 'A';
    else
        return c;
}
//将十六进制的字符串转换成整数
long str_num16(char s[])
{
    int i;
    long n = 0;
    if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
        i = 2;
    else
        i = 0;
    for (; (s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z'); ++i)
    {
        if (tolower(s[i]) > '9')
            n = 16 * n + (10 + tolower(s[i]) - 'a');
        else
            n = 16 * n + (tolower(s[i]) - '0');
    }
    return n;
}
//将十进制的字符串转换成整数
long str_num10(char *str)
{
    char *p;
    long x = 0;
    int i = 0;

    for (p = str; *p != '\0'; p++)
    {
        if (*p >= '0' && *p <= '9')
            i = *p - '0';
        x = x * 10 + i;
    }
    return x;
}

int main(int argc, char **argv)
{
    long s = 0;
    long s1 = 0;
    long sum = 0;
    /*检查是否两个输入*/
    if (argc - 1 != 2)
    {
        cout << "ERROR" << endl;
        return 1;
    }
    /*检查输入长度是否不超过10*/
    const string arg1 = argv[1];
    const string arg2 = argv[2];
    if(arg1.length() >10 || arg2.length() >10)
    {  
        cout<<"ERROR"<<endl; 
        return 1;
    } 
    string pattern = "0[xX][0-9a-fA-F]+";
    regex re(pattern);
    string pattern2 = "^[0-9]*$";
    regex reg(pattern2);
    /*判断第一个输入是否符合16进制或是10进制*/
    if (!regex_match(arg1, re) && !regex_match(arg1, reg))
    {
        cout << "ERROR" << endl;
        return 1;
    }
    /*判断第二个输入是否符合16进制或是10进制*/
    if (!regex_match(arg2, reg) && !regex_match(arg2, re))
    {
        cout << "ERROR" << endl;
        return 1;
    }
    // 未考虑两个输入都是16进制或是10进制 //
    if (regex_match(arg1, re))
    {
        s = str_num16(argv[1]);
        s1 = str_num10(argv[2]);
    }
    else
    {
        s = str_num16(argv[2]);
        s1 = str_num10(argv[1]);
    }
    sum = s + s1;

    /*10进制数转换为16进制 */
    char buf[10] = {0};
    sprintf(buf, "0x%X", sum);

    cout << buf << "  " << sum << endl;
    return 0;
}

运行结果如下:

➜   g++ tmp.cpp -o tmp     
➜   ./tmp 0x10 1
0x11  17
➜   ./tmp 10 0x1
0xB  11
➜   ./tmp 0xgfhfg 12
ERROR
➜   ./tmp 0x12345677777 0xhello
ERROR
3. C语言中正则表达式示例
#include<stdio.h>                                                                                                        
#include<sys/types.h>
#include<regex.h>
#include<memory.h>
#include<stdlib.h>

int main(){
    char *bematch = "0x101111";
    char *pattern = "0[xX][0-9a-fA-F]+";
    char errbuf[50];
    char match[50];
    regex_t reg;
    int err,nm = 10;
    regmatch_t pmatch[nm];

    if(regcomp(&reg,pattern,REG_EXTENDED) < 0){
        regerror(err,&reg,errbuf,sizeof(errbuf));
        printf("err:%s\n",errbuf);
    }
    err = regexec(&reg,bematch,nm,pmatch,0);

    if(err == REG_NOMATCH){
        printf("no match\n");
        exit(-1);
    }
    for(int i=0;i<10 && pmatch[i].rm_so!=-1;i++){
        int len = pmatch[i].rm_eo-pmatch[i].rm_so;
        if(len){
            memset(match,'\0',sizeof(match));
            memcpy(match,bematch+pmatch[i].rm_so,len);
            printf("match : %s\n",match);
        }
    }
    return 0;
}

References:
  • https://zhuanlan.zhihu.com/p/30573054
  • http://www.cplusplus.com/reference/regex/regex_match/
  • https://www.cnblogs.com/274914765qq/p/4574367.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值