在 C++ 中用 "DEFINED" 子表达式组成复杂的正则表达式
Composing complex regular expressions with "DEFINED" subexpressions in C++
我正在尝试用 C++ 编写正则表达式来匹配 base64 编码的字符串。我非常熟悉在 Perl 中编写复杂的正则表达式,所以我从它开始:
use strict;
use warnings;
my $base64_regex = qr{
(?(DEFINE)
(?<B64>[A-Za-z0-9+/])
(?<B16>[AEIMQUYcgkosw048])
(?<B04>[AQgw])
)
^(
((?&B64){4})*
(
(?&B64){4}|
(?&B64){2}(?&B16)=|
(?&B64)(?&B04)={2}
)
)?$}x;
# "Hello World!" base64 encoded
my $base64 = "SGVsbG8gV29ybGQh";
if ($base64 =~ $base64_regex)
{
print "Match!\n";
}
else
{
print "No match!\n"
}
输出:
Match!
然后我尝试用 C++ 实现一个类似的正则表达式:
#include <iostream>
#include <regex>
int main()
{
std::regex base64_regex(
"(?(DEFINE)"
"(?<B64>[A-Za-z0-9+/])"
"(?<B16>[AEIMQUYcgkosw048])"
"(?<B04>[AQgw])"
")"
"^("
"((?&B64){4})*"
"("
"(?&B64){4}|"
"(?&B64){2}(?&B16)=|"
"(?&B64)(?&B04)={2}"
")"
")?$");
// "Hello World!" base64 encoded
std::string base64 = "SGVsbG8gV29ybGQh";
if (std::regex_match(base64, base64_regex))
{
std::cout << "Match!" << std::endl;
}
else
{
std::cout << "No Match!" << std::endl;
}
}
但是当我 运行 代码时,我得到一个异常告诉我它不是一个有效的正则表达式。
捕获异常并打印“what”字符串也无济于事。它给我的是以下内容:
regex_error(error_syntax)
显然我可以用预定义的子模式摆脱“DEFINE”块,但这会使整个表达式很难阅读......而且,好吧......我希望能够保持几年后我回过头来使用我自己的代码,哈哈,所以这不是一个好的选择。
如何获得类似的正则表达式以在 C++ 中工作?
注意:这一切都必须在单个“std::regex”对象中完成,因为我正在编写一个库,用户可以在其中传递字符串以定义自己的正则表达式,我希望这些用户能够在需要时在他们的正则表达式中“定义”类似的子表达式。
字符串连接如何?
#define B64 "[A-Za-z0-9+/]"
#define B16 "[AEIMQUYcgkosw048]"
#define B04 "[AQgw]"
std::regex base64_regex(
"^("
"(" B64 "{4})*"
"("
B64 "{4}|"
B64 "{2}" B16 "=|"
B64 B04 "={2}"
")"
")?$");
我从评论中采纳了一个建议并检查了“boost”正则表达式,因为它支持“Perl”正则表达式。我试了一下,效果很好!
#include <boost/regex.hpp>
boost::regex base64_regex(
"(?(DEFINE)"
"(?<B64>[A-Za-z0-9+/])"
"(?<B16>[AEIMQUYcgkosw048])"
"(?<B04>[AQgw])"
")"
"("
"((?&B64){4})*"
"("
"(?&B64){4}|"
"(?&B64){2}(?&B16)=|"
"(?&B64)(?&B04)={2}"
")"
")?", boost::regex::perl);
我正在尝试用 C++ 编写正则表达式来匹配 base64 编码的字符串。我非常熟悉在 Perl 中编写复杂的正则表达式,所以我从它开始:
use strict;
use warnings;
my $base64_regex = qr{
(?(DEFINE)
(?<B64>[A-Za-z0-9+/])
(?<B16>[AEIMQUYcgkosw048])
(?<B04>[AQgw])
)
^(
((?&B64){4})*
(
(?&B64){4}|
(?&B64){2}(?&B16)=|
(?&B64)(?&B04)={2}
)
)?$}x;
# "Hello World!" base64 encoded
my $base64 = "SGVsbG8gV29ybGQh";
if ($base64 =~ $base64_regex)
{
print "Match!\n";
}
else
{
print "No match!\n"
}
输出:
Match!
然后我尝试用 C++ 实现一个类似的正则表达式:
#include <iostream>
#include <regex>
int main()
{
std::regex base64_regex(
"(?(DEFINE)"
"(?<B64>[A-Za-z0-9+/])"
"(?<B16>[AEIMQUYcgkosw048])"
"(?<B04>[AQgw])"
")"
"^("
"((?&B64){4})*"
"("
"(?&B64){4}|"
"(?&B64){2}(?&B16)=|"
"(?&B64)(?&B04)={2}"
")"
")?$");
// "Hello World!" base64 encoded
std::string base64 = "SGVsbG8gV29ybGQh";
if (std::regex_match(base64, base64_regex))
{
std::cout << "Match!" << std::endl;
}
else
{
std::cout << "No Match!" << std::endl;
}
}
但是当我 运行 代码时,我得到一个异常告诉我它不是一个有效的正则表达式。
捕获异常并打印“what”字符串也无济于事。它给我的是以下内容:
regex_error(error_syntax)
显然我可以用预定义的子模式摆脱“DEFINE”块,但这会使整个表达式很难阅读......而且,好吧......我希望能够保持几年后我回过头来使用我自己的代码,哈哈,所以这不是一个好的选择。
如何获得类似的正则表达式以在 C++ 中工作?
注意:这一切都必须在单个“std::regex”对象中完成,因为我正在编写一个库,用户可以在其中传递字符串以定义自己的正则表达式,我希望这些用户能够在需要时在他们的正则表达式中“定义”类似的子表达式。
字符串连接如何?
#define B64 "[A-Za-z0-9+/]"
#define B16 "[AEIMQUYcgkosw048]"
#define B04 "[AQgw]"
std::regex base64_regex(
"^("
"(" B64 "{4})*"
"("
B64 "{4}|"
B64 "{2}" B16 "=|"
B64 B04 "={2}"
")"
")?$");
我从评论中采纳了一个建议并检查了“boost”正则表达式,因为它支持“Perl”正则表达式。我试了一下,效果很好!
#include <boost/regex.hpp>
boost::regex base64_regex(
"(?(DEFINE)"
"(?<B64>[A-Za-z0-9+/])"
"(?<B16>[AEIMQUYcgkosw048])"
"(?<B04>[AQgw])"
")"
"("
"((?&B64){4})*"
"("
"(?&B64){4}|"
"(?&B64){2}(?&B16)=|"
"(?&B64)(?&B04)={2}"
")"
")?", boost::regex::perl);