Arduino 正则匹配不规则字符串

在Arduino解析字符串时,对于规则字符串内容,常用的有Json解析,或者是按位置获取从N到N+1位的内容,但对于不规则字符串,则只能使用查找的方式去获取,例如String.find。
以下内容介绍使用正则表达式去匹配查找或替换指定内容,使用前需了解什么是正则表达式

本示例使用Regexp库实现正则表达式的使用,该库使用以下三个C标准库实现,因此理论可直接在C框架移植使用,实测在STM32CubeMX可用。

#include <setjmp.h>   //属于C函数库,作用是分别承担非局部标号和goto作用。
#include <ctype.h>    //是C标准函数库中的头文件,定义了一批C语言字符分类函数
#include <string.h>   //是C语言标准库,在使用到字符数组时需要使用

示例代码1

以下实例将从字符串中获取所有的带小数点的数据并打印至串口中

点击查看代码
#include <Arduino.h>
#include <Regexp.h>

// called for each match
void match_callback(const char *match,         // matching string (not null-terminated)
                    const unsigned int length, // length of matching string
                    const MatchState &ms)      // MatchState in use (to get captures)
{
  char cap[10]; // must be large enough to hold captures

  Serial.print("Matched: ");
  Serial.write((byte *)match, length);
  Serial.println();

  for (word i = 0; i < ms.level; i++)
  {
    Serial.print("Capture ");
    Serial.print(i, DEC);
    Serial.print(" = ");
    ms.GetCapture(cap, i);
    Serial.println(cap);
  } // end of for each capture

} // end of match_callback

void testFunc()
{
  unsigned long count;

  // what we are searching (the target)
  char buf[100] = "content:a1.1 bb22.22ccc333.333dddd4444.666 ";

  // match state object
  MatchState ms(buf);

  // original buffer
  Serial.println(buf);

  // search for three letters followed by a space (two captures)
  count = ms.GlobalMatch("%d+%.%d+", match_callback);

  // show results
  Serial.print("Found ");
  Serial.print(count); // 8 in this case
  Serial.println(" matches.");
}

void setup()
{
  Serial.begin(9600);
  Serial.println();

} // end of setup

void loop()
{
  Serial.printf("\n\n");
  testFunc();
  delay(5 * 1000);
}

效果演示

实例代码2

以上示例实现了简单的正则匹配指定内容,那么如果需要单次匹配多个指定规则内容,比如在以上的实例字符串中,数字前面的字母内容为关键字,需要同时捕获,则参考以下代码

点击查看代码
#include <Arduino.h>
#include <Regexp.h>

// called for each match
void match_callback(const char *match,         // matching string (not null-terminated)
                    const unsigned int length, // length of matching string
                    const MatchState &ms)      // MatchState in use (to get captures)
{
  char cap[10]; // must be large enough to hold captures

  Serial.print("Matched: ");
  Serial.write((byte *)match, length);
  Serial.println();

  for (word i = 0; i < ms.level; i++)
  {
    Serial.print("Capture ");
    Serial.print(i, DEC);
    Serial.print(" = ");
    ms.GetCapture(cap, i);
    Serial.println(cap);
  } // end of for each capture

} // end of match_callback

void testFunc()
{
  unsigned long count;

  // what we are searching (the target)
  char buf[100] = "content:a1.1 bb22.22ccc333.333dddd4444.666 ";

  // match state object
  MatchState ms(buf);

  // original buffer
  Serial.println(buf);

  // search for three letters followed by a space (two captures)
  count = ms.GlobalMatch("(%a+)(%d+%.%d+)", match_callback);

  // show results
  Serial.print("Found ");
  Serial.print(count); // 8 in this case
  Serial.println(" matches.");
}

void setup()
{
  Serial.begin(9600);
  Serial.println();

} // end of setup

void loop()
{
  Serial.printf("\n\n");
  testFunc();
  delay(5 * 1000);
}

效果演示

使用该库提示

在使用Arduino-Regexp正则库时,须知%为魔术字符,例如常规语言正则匹配数字为\d,但在这里需使用%d,这一点需区别开来
以下是该库的一些规则须知,Regexp-Arduino简单文档

库的特点

作者在设计库的时候,遵循以下三条预想去实现,

My design criteria for this library were:

Be powerful enough to be useful (ie. not a "toy")
Be fast enough that it could be used to do things like process input from GPS devices, RFID readers, web pages etc.
Be compact enough that it doesn't use most of the available memory on a microprocessor

内容源自本链接

速度测试

Lua正则表达式匹配器因其速度而备受好评,这个库的性能也很好。例如:
解析字符串:"Testing: answer=42"
正则表达式: "(%a+)=(%d+)"
匹配所需的时间:在16 MHz的Arduino微处理器上运行大约2毫秒。
这个测试返回匹配的文本("answer=42")、它的长度以及两个捕获("answer"和"42")。

posted @ 2022-09-04 20:14  Dapenson  阅读(861)  评论(0编辑  收藏  举报