生成正则表达式的所有可能匹配项
Generate All Possible Matches of a Regular Expression
如何导出正则表达式的所有可能匹配项
例如:
((a,b,c)o(m,v)p,b)
从上面的表达式生成的字符串将是:
aomp
bomp
comp
aovp
bovp
covp
b
您的步骤非常简单,但实施它们可能需要一些工作:
- 创建一个递归函数,提取第一组括号之间的字符串:
- 在函数中将
','
上的字符串拆分为 vector<string>
和 return 它:
- 在 return 测试是否由于嵌套括号而需要递归之前,必须为递归函数 returned 的每个可能组合添加一个字符串到 return
编辑:
假设我的输入字符串是“(bl(ah,eck,le),yap)”
- 第一个函数将提取
string
:"bl(ah,eck,le),yap"
- 在 returning 之前它会搜索嵌套的括号,这会导致它递归:
- 第二个函数将提取
string
:"ah,eck,le"
- 在 returning 之前它会搜索嵌套的括号并找到 none
- 它将 return 一个
vector<string>
: ["ah","eck","le"]
- 第一个函数现在包含:“bl["ah","eck","le"],yap”
- 它不会再找到要提取的括号,所以它会展开所有内部组合:“["blah","bleck","blle"],yap”
- 它现在可以拆分字符串和 return:["blah"、"bleck"、"blle"、"yap"]
第一个函数的 return 就是你的结果。
编辑:
很高兴你解决了它我也写了一个双状态机来解决它所以我想我可以post在这里供你比较:
const char* extractParenthesis(const char* start, const char* finish){
int count = 0;
return find_if(start, finish, [&](char i){
if (i == '('){
count++;
}
else if (i == ')'){
count--;
}
return count <= 0; });
}
vector<string> split(const char* start, const char* finish){
const char delimiters[] = ",(";
const char* it;
vector<string> result;
do{
for (it = find_first_of(start, finish, begin(delimiters), end(delimiters));
it != finish && *it == '(';
it = find_first_of(extractParenthesis(it, finish) + 1, finish, begin(delimiters), end(delimiters)));
auto&& temp = interpolate(start, it);
result.insert(result.end(), temp.begin(), temp.end());
start = ++it;
} while (it <= finish);
return result;
}
vector<string> interpolate(const char* start, const char* finish){
vector<string> result{ 1, string{ start, find(start, finish, '(') } };
for (auto it = start + result[0].size();
it != finish;
it = find(++start, finish, '('),
for_each(result.begin(), result.end(), [&](string& i){ i += string{ start, it }; })){
start = extractParenthesis(it, finish);
auto temp = split(next(it), start);
const auto size = result.size();
result.resize(size * temp.size());
for (int i = result.size() - 1; i >= 0; --i){
result[i] = result[i % size] + temp[i / size];
}
}
return result;
}
根据您的编译器,您需要转发声明它们,因为它们会相互调用。如果输入字符串格式不正确,这也会崩溃。而且它不能处理转义的控制字符。
无论如何你可以这样称呼它:
const char test[] = "((a,b,c)o(m,v)p,b)";
auto foo = interpolate(begin(test), end(test));
for (auto& i : foo){
cout << i << endl;
}
如何导出正则表达式的所有可能匹配项
例如:
((a,b,c)o(m,v)p,b)
从上面的表达式生成的字符串将是:
aomp
bomp
comp
aovp
bovp
covp
b
您的步骤非常简单,但实施它们可能需要一些工作:
- 创建一个递归函数,提取第一组括号之间的字符串:
- 在函数中将
','
上的字符串拆分为vector<string>
和 return 它: - 在 return 测试是否由于嵌套括号而需要递归之前,必须为递归函数 returned 的每个可能组合添加一个字符串到 return
编辑:
假设我的输入字符串是“(bl(ah,eck,le),yap)”
- 第一个函数将提取
string
:"bl(ah,eck,le),yap" - 在 returning 之前它会搜索嵌套的括号,这会导致它递归:
- 第二个函数将提取
string
:"ah,eck,le" - 在 returning 之前它会搜索嵌套的括号并找到 none
- 它将 return 一个
vector<string>
: ["ah","eck","le"]
- 第二个函数将提取
- 第一个函数现在包含:“bl["ah","eck","le"],yap”
- 它不会再找到要提取的括号,所以它会展开所有内部组合:“["blah","bleck","blle"],yap”
- 它现在可以拆分字符串和 return:["blah"、"bleck"、"blle"、"yap"]
第一个函数的 return 就是你的结果。
编辑:
很高兴你解决了它我也写了一个双状态机来解决它所以我想我可以post在这里供你比较:
const char* extractParenthesis(const char* start, const char* finish){
int count = 0;
return find_if(start, finish, [&](char i){
if (i == '('){
count++;
}
else if (i == ')'){
count--;
}
return count <= 0; });
}
vector<string> split(const char* start, const char* finish){
const char delimiters[] = ",(";
const char* it;
vector<string> result;
do{
for (it = find_first_of(start, finish, begin(delimiters), end(delimiters));
it != finish && *it == '(';
it = find_first_of(extractParenthesis(it, finish) + 1, finish, begin(delimiters), end(delimiters)));
auto&& temp = interpolate(start, it);
result.insert(result.end(), temp.begin(), temp.end());
start = ++it;
} while (it <= finish);
return result;
}
vector<string> interpolate(const char* start, const char* finish){
vector<string> result{ 1, string{ start, find(start, finish, '(') } };
for (auto it = start + result[0].size();
it != finish;
it = find(++start, finish, '('),
for_each(result.begin(), result.end(), [&](string& i){ i += string{ start, it }; })){
start = extractParenthesis(it, finish);
auto temp = split(next(it), start);
const auto size = result.size();
result.resize(size * temp.size());
for (int i = result.size() - 1; i >= 0; --i){
result[i] = result[i % size] + temp[i / size];
}
}
return result;
}
根据您的编译器,您需要转发声明它们,因为它们会相互调用。如果输入字符串格式不正确,这也会崩溃。而且它不能处理转义的控制字符。
无论如何你可以这样称呼它:
const char test[] = "((a,b,c)o(m,v)p,b)";
auto foo = interpolate(begin(test), end(test));
for (auto& i : foo){
cout << i << endl;
}