代码非常简单,但是C++的regex库功能非常全面,提供了perl格式正则表达式,posix extend正则表达式和posix basic正则表达式三种正则表达式模式。
本人试了半天,发现posix extend这种模式和我们平常用的正则表达式模式一致,所以建议直接posix extend就够了。
代码如下,
CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(lexical_cast)
add_definitions(-std=c++14)
include_directories("/usr/local/include")
link_directories("/usr/local/lib")
file( GLOB APP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
foreach( sourcefile ${APP_SOURCES} )
file(RELATIVE_PATH filename ${CMAKE_CURRENT_SOURCE_DIR} ${sourcefile})
string(REPLACE ".cpp" "" file ${filename})
add_executable(${file} ${sourcefile})
target_link_libraries(${file} boost_filesystem boost_regex boost_thread boost_system boost_serialization pthread boost_chrono)
endforeach( sourcefile ${APP_SOURCES} )
main.cpp
#include <boost/regex.hpp>
#include <iostream>
int main(int argc, char* argv[]) {
std::cout <<
"Available regex syntaxes:\n" <<
"\t[0] Perl\n" <<
"\t[1] Perl case insensitive\n" <<
"\t[2] POSIX extented\n" <<
"\t[3] POSIX extented case insensitive\n" <<
"\t[4] POSIX basic\n" <<
"\t[5] POSIX basic case insensitive\n" <<
"Choose regex syntax: ";
boost::regex::flag_type flag;
// 让用户选择正则表达式语法
switch(std::cin.get()) {
case '0':
flag = boost::regex::perl;
break;
case '1':
flag = boost::regex::perl | boost::regex::icase;
break;
case '2':
flag = boost::regex::extended;
break;
case '3':
flag = boost::regex::extended | boost::regex::icase;
break;
case '4':
flag = boost::regex::basic;
break;
case '5':
flag = boost::regex::basic | boost::regex::icase;
break;
default:
std::cerr << "Incorrect number of regex syntax, Exiting...\n";
return -1;
}
// 不让regex构造函数抛异常
// 关于C++的两个不成文规定了解下,构造函数有异常需要抛出异常,千万不要在析构函数抛出异常
// 所以构造函数是可以抛出异常的
// 这里不让构造函数 抛出异常的原因是,在while循环中,一次构造失败不影响下一次输入正确的表达式
// 可以使用错误码检测的机制来阻止异常发生,而不是简单的抛出异常,停止程序
// 或者抛出异常,捕获异常
// 因为根据异常来判断程序是否执行成功不可取,这种代码不具有可测性,不到不得已不要为之
// 面试中写出根据异常判断程序是否成功,估计就要等通知了
flag |= boost::regex::no_except;
// 清空std::cin
std::cin.ignore();
std::cin.clear();
std::string regex, str;
do {
std::cout << "Input regex: ";
if(!std::getline(std::cin, regex) || regex.empty()) {
return 0;
}
// 如果不设置 不抛出异常,构造函数可能会抛出异常
const boost::regex e(regex, flag);
if(e.status()) {
std::cerr << "Incorrect regex pattern!\n";
continue;
}
std::cout << "String to match: ";
while(std::getline(std::cin, str) && !str.empty()) {
bool matched = boost::regex_match(str, e);
std::cout << (matched ? "MATCH\n": "DOES NOT MATCH\n");
std::cout << "String to match: ";
}
std::cout << '\n';
// 清空std::cin
std::cin.ignore();
std::cin.clear();
} while(1);
}
程序输出如下,
关于库的链接方面,这里有个坑。
本文只讲述C++最常使用的操作平台 Linux平台的配置。
如果你是在ubuntu平台使用regex库,需要自己手动安装一下libcu库,然后添加对应的链接目录。不然的话,编译器在链接boost_regex库时,会报找不到相关函数错误。
当然现代C++编译相当智能,直接会告诉你缺失的libcu库的版本,直接下载相应版本的库就可以。
值得注意的一点是,直接使用类似apt get的方式安装可能不行。
比如我的boost库是1.75版本,boost_regex库依赖于 libcu60版本。
而我本身的ubuntu操作系统是20.04版本,它本身的源里面的libcu库大于60版本。
libcu60版本的库是提供给ubuntu 18.04的。
这时apt-get install就会报找不到libcu60。
解决方案就是到ubuntu官方源手动下载,然后用apt-get install ***.deb。
其他方案好像都不行。vcpkg安装没试过。
如果你是缺少libcu60,可以在如下地址下载,
http://archive.ubuntu.com/ubuntu/pool/main/i/icu/libicu60_60.2-3ubuntu3_amd64.deb
网友评论