本周小贴士#64:原生字符串字面量

作为totw/64最初发表于2019年12月9日

由Titus Winters (titus@google.com)创作

更新于2017年10月23日

“(?:”(?:\\"|["])*"|’(?:\\’|[’])*’)";——一只猫走过键盘…或者可能是一只狐狸说的…不是的,实际上这只是在真实C++代码中的一个高度转义的正则表达式。

由于转义的问题,你可能在正确理解正则表达式上遇到麻烦。同样地,当你将Protobuf或JSON数据的文本嵌入你的程序中时,你可能对保留引号和换行符感到恼怒。当你必须使用重要的转义(或更糟的是,多层转义)时,代码的可读性显著下降。

幸运的是,有一个新的C++11特性消除了这种转义需求:原生字符串字面量。

原生字符串字面量格式化

原生字符串字面量有如下特定语法:

R"tag(whatever you want to say)tag"

标签是最多16个字符的序列(空标签是可行又常见的)。’’‘tag(首次出现之后)tag’’'之前的字符是被当作字符串字面量使用。'tag’可以包括除了括号、反斜杠和空格之外的任意字符。

检测不同:

const char concert_17_raw[] =
    "id: 17\n"
    "artist: \"Beyonce\"\n"
    "date: \"Wed Oct 10 12:39:54 EDT 2012\"\n"
    "price_usd: 200\n";

与之相对:

const char concert_17_raw[] = R"(
    id: 17
    artist: "Beyonce"
    date: "Wed Oct 10 12:39:54 EDT 2012"
    price_usd: 200)";

特殊案例

请注意缩进规则,结合实际情况,原生字符串字面常量可能包括换行符,这让你在选择如何缩进原生字符串第一行时面临尴尬。因为文件Protobufs会忽略空白,所以在这种情况下,这个问题可以通过引入换行符(被分析器忽略)来避免,但并非所有的原生字符串都是如此宽松的。

当序列)"出现在你的字符串中,非空tag是有用的,因此它不能作为结束分隔符:

std::string my_string = R"foo(This contains quoted parens "()")foo";

结论

原生字符串字面量肯定不是我们大多数人日常的工具,但有时更好地使用这种新语言特性将增加可读性。因此,下次你挠头试图弄清楚是否要两个\或四个时,请尝试用原生字符串字面量来代替。你的读者将因为它而感谢你,即便正则表达式依然很难。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值