在嵌入式开发中,尤其是串口通信,不大可能会用xml或json之类,那个解析太复杂,而且通信负载也重,通常组装一个简单的表达式作为协议,然后解析一下就好。以前用nodemcu的时候,发现lua处理正则表达式功能特别强大特别好用,后来发现java,c++都有类似功能,这样的就给单片机和android手机和pc通信提供便利,协议就是一个表达式,简单且够用,处理起来也简单。
这是lua模式匹配相关教程:http://lua-users.org/wiki/PatternsTutorial
> = string.match("one |two| three |four| five", '|.*|')
|two| three |four|
> = string.match("one |two| three |four| five", '|.-|')
|two|
> = string.match("one |two| three |four| five", '|[^|]*|') -- another solution can be to not let the contents match the delimiter
|two|
c++正则表达式在字符串中处理教程:http://en.cppreference.com/w/cpp/regex/regex_match
#include <iostream>
#include <string>
#include <regex>
int main()
{
// Simple regular expression matching
std::string fnames[] = {"foo.txt", "bar.txt", "baz.dat", "zoidberg"};
std::regex txt_regex("[a-z]+\\.txt");
for (const auto &fname : fnames) {
std::cout << fname << ": " << std::regex_match(fname, txt_regex) << '\n';
}
// Extraction of a sub-match
std::regex base_regex("([a-z]+)\\.txt");
std::smatch base_match;
for (const auto &fname : fnames) {
if (std::regex_match(fname, base_match, base_regex)) {
// The first sub_match is the whole string; the next
// sub_match is the first parenthesized expression.
if (base_match.size() == 2) {
std::ssub_match base_sub_match = base_match[1];
std::string base = base_sub_match.str();
std::cout << fname << " has a base of " << base << '\n';
}
}
}
// Extraction of several sub-matches
std::regex pieces_regex("([a-z]+)\\.([a-z]+)");
std::smatch pieces_match;
for (const auto &fname : fnames) {
if (std::regex_match(fname, pieces_match, pieces_regex)) {
std::cout << fname << '\n';
for (size_t i = 0; i < pieces_match.size(); ++i) {
std::ssub_match sub_match = pieces_match[i];
std::string piece = sub_match.str();
std::cout << " submatch " << i << ": " << piece << '\n';
}
}
}
}
java 正则表达式在字符串中处理例子:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatcherTest {
public static void main(String[] args) throws Exception {
MatcherTest test = new MatcherTest();
test.test1();
test.test2();
}
public void test1()
{
System.out.println("test1...............................");
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("我的QQ是:456456 我的电话是:0532214 我的邮箱是:aaa123@aaa.com");
while(m.find()) {
System.out.println(m.group());
}
}
public void test2() {
System.out.println("test2...............................");
Pattern p=Pattern.compile("([a-z]+)(\\d+)");
Matcher m=p.matcher("aaa2223bb");
m.find(); //匹配aaa2223
for(int i = 0; i < m.groupCount(); i ++)//表达式里带括号了,分组了,这个lua也是类似的
{
System.out.println(m.group(i));
}
}
}
其实 arduino也实现了一个库,完全跟lua的正则表达式兼容的:https://github.com/Arduino-and-RaspberryPi/Regexp
不过这里注意一下,lua只有match只是想当于regex_search,所以不要搞混了
下面是c++正则表达式各种演示:
// HelloRegularExpression.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <string>
#include <regex>
#include <iostream>
using namespace std;
//这个 match是要整个字符串匹配到,前后加了任何东西都算匹配失败
//match是全文匹配,即要求整个字符串符合匹配规则。
void testMatch()
{
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
}
cout << "======================================================" << endl;
//遍历结果
for (int i = 0; i < result.size(); ++i)
{
cout << result[i] << endl;
}
//-------------------- -
// 作者:Rhine404
// 来源:CSDN
// 原文:https ://blog.csdn.net/qq_34802416/article/details/79307102
//版权声明:本文为博主原创文章,转载请附上博文链接!
}
void testSearch()
{
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; //更新搜索起始位置,搜索剩下的字符串
}
}
//这种操作跟lua的是基本就一样了
void testSearch1()
{
string str = "Hello_2018, Hello_2017 Hi!!!_2019";
smatch result;
regex pattern("(.{5})_(\\d{4})"); //匹配四个数字
//迭代器声明
string::const_iterator iterStart = str.begin();
string::const_iterator iterEnd = str.end();
string temp;
string sub1;
string sub2;
while (regex_search(iterStart, iterEnd, result, pattern))
{
temp = result[0];
sub1 = result[1];
sub2 = result[2];
cout << temp << " " << sub1 << " " << sub2 << endl;
iterStart = result[0].second; //更新搜索起始位置,搜索剩下的字符串
}
}
void testReplace()
{
string str = "Hello_2018!Hello_2019!";
regex pattern("Hello");
cout << regex_replace(str, pattern, "") << endl; //输出:_2018,将Hello替换为""
cout << regex_replace(str, pattern, "Hi") << endl; //输出:Hi_2018,将Hello替换为Hi
}
void testReplace1()
{
string str = "Hello_2018! Hello_2019";
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,交换位置顺序
}
void testIgnorUpLowCase()
{
cout << regex_match("aaaAAA", regex("a*", regex::icase)) << endl; //结果为1
cout << regex_match("aaaAAA", regex("a*")) << endl; //结果为0
}
int main()
{
testMatch();
testSearch();
testSearch1();
testReplace();
testReplace1();
testIgnorUpLowCase();
getchar();
return 0;
}