我刚开始使用Boost :: xpressive并发现它是一个很棒的库...我浏览了文档并尝试使用!运算符(零或一)但它不编译(VS2008)。
我想匹配一个SIP地址,该地址可能是也可能不是以“sip:”
开头#include <iostream>
#include <boost/xpressive/xpressive.hpp>
using namespace boost::xpressive;
using namespace std;
int main()
{
sregex re = !"sip:" >> *(_w | '.') >> '@' >> *(_w | '.');
smatch what;
for(;;)
{
string input;
cin >> input;
if(regex_match(input, what, re))
{
cout << "match!\n";
}
}
return 0;
}`
答案 0 :(得分:8)
你刚刚遇到了一个困扰大部分DSEL的错误。
问题是您希望调用特定的运算符,即在您的特定语言中实际定义的运算符。但是,此运算符已存在于C ++中,因此适用于查找和重载分辨率的常规规则。
右运算符的选择是通过ADL(Argument Dependent Lookup)完成的,这意味着运算符所适用的对象中至少有一个应该是DSEL本身的一部分。
例如,请考虑以下简单的代码段:
namespace dsel
{
class MyObject;
class MyStream;
MyStream operator<<(std::ostream&, MyObject);
}
int main(int, char*[])
{
std::cout << MyObject() << "other things here";
}
因为表达式是从左到右评估的,dsel::MyObject
的存在是病毒式的,即dsel将在这里传播。
关于Xpressive
,大部分时间都可以使用,因为您使用Xpressive
类型实例(_w
)的特殊“标记”或因为病毒效应(例如“ @“有效,因为>>
左侧的表达式是Xpressive
- 相关的。)
你要使用:
sregex re = "sip:" >> *(_w | '.') >> '@' >> *(_w | '.');
^^^^^^ ~~ ^^^^^^^^^^^
Regular Xpressive
这样可行,因为由于操作符的优先级规则,右侧参数被Xpressive
“污染”。
但是operator!
有一个最高优先级。在这种情况下,其范围仅限于:
`!"sip:"`
由于"sip:"
的类型为char const[5]
,因此它只会调用常规operator!
,这将正确地推断出它应用的表达式为true
,从而评估为bool
值false
。
通过使用as_xpr
,您可以将C字符串转换为Xpressive
对象,从而将operator!
命名空间中的右Xpressive
引入考虑范围,并超载决议适当地开始。
答案 1 :(得分:1)
as_xpr
帮助...
!as_xpr("sip:")