我第一次尝试在像这样的一些字符串上使用 C++
std::regex_math
,并且我尝试提取 A、e、guard、action 和 B(如果可用)。
hsm::state<A> = hsm::state<B>
hsm::state<A> + hsm::event<e> = hsm::state<B>
hsm::state<A> [guard] = hsm::state<B>
hsm::state<A> / action = hsm::state<B>
hsm::state<A> + hsm::event<e> [guard] = hsm::state<B>
hsm::state<A> [guard] / action = hsm::state<B>
hsm::state<A> + hsm::event<e> [guard] / action = hsm::state<B>
所以我可以稍后生成一些 plantuml 状态图。 通常,我会进行一些分割/修剪,但我决定学习正则表达式......到目前为止,我已经了解了下面的代码。
几乎是正确的。它仍然是抵抗我的事件、守卫和行动。我没有成功删除不需要的字符
m[2]: event : [ + hsm::event<e>]
m[3]: guard : [ [guard]]
m[4]: action: [ / action ]
此处为“+”、“[”和“]”以及“/”。
有什么建议可以更进一步吗?
问候,
这是我的最后一次尝试:
#include <fstream>
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main(int argc, char* argv[])
{
std::regex re{"(.*hsm::state<.[^>]*>)(.*hsm::event<.[^>]*>)?(.*\\[.[^>]*\\])?(.*/.[^=]*)?.*(hsm::state<.[^>]*>).*"};
ifstream file(argv[1]);
for (std::string line; getline(file, line);) {
cout << "[" << line << "]" << endl;
std::smatch match;
if (std::regex_match(line, match, re)) {
const char* names[] = {"", "source", "event ", "guard ", "action", "target", "", "", ""};
for (size_t i = 1; i < match.size(); ++i) {
cout << " m[" << i << "]: " << names[i] << ": [" << match[i] << "]" << endl;
}
}
}
}
我想避免多次通过,这主要是我到目前为止所做的。
所以我想出了这个。为每个部分分割 RE,一些非捕获组,以及大量空间丢弃(而不是解析之前的全局 std::remove_if)。
如果有更好的,我就接受了(没有对像 + hsm::event 这样的组合组进行验证<...>)
std::regex re{// source
R"(hsm::state<(\w*)>\s*)"
// optional event
R"(\+?\s*)"
R"((?:hsm::event<)?(\w*)(?:>)?\s*)"
// optional guard
R"(\[?(\w*)\]?\s*)"
// optional action
R"(/?\s*)"
R"((\w*)\s*)"
// target
R"(=\s*)"
R"(hsm::state<(\w*)>)"};