Tip of the Week #64: Raw String Literals
Posted zhangyifei216
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tip of the Week #64: Raw String Literals相关的知识,希望对你有一定的参考价值。
Tip of the Week #64: Raw String Literals
Originally published as totw/64 on 2013-12-09
By Titus Winters (titus@google.com)
Updated 2017-10-23
Quicklink: abseil.io/tips/64
“(?:”(?:\\\\"|["])*"|’(?:\\\\’|[’])*’)"; — A cat walking over the keyboard . . . or maybe what the fox says . . . no, actually just a highly- escaped regexp found in real C++ code.
奇怪的是在C++中你可能会因为转义的问题导致你无法理解正常的正则表达式。同样,你在将Protobuf
或者是JSON
数据嵌入到单元测试中的文本时,您可能会因为要保留引号和换行符而感到恼火。当你必须使用转义(或者更为糟糕的多重转义的时)时,代码的清晰度会急剧下降。
幸运的是,有一个新的C++11的特性raw string literals
,它消除了转义的需要。
The Raw String Literal Format
一个raw string literals
具有如下的语法格式:
R"tag(whatever you want to say)tag"
tag
是一个最多16个字符的序列(空的tag
也是可以的)。"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)";
Special Cases
注意锁进规则,当遇到raw string literals
可能会包含新行的情况,会让你面临如何对原始字符串的第一行进行锁进的尴尬的选择。因为protobuf
的文本是忽略空白的,所以可以通过添加一个前导\\n
来避免这个问题,但是不是所有的原始字符串的使用都如此宽容。
当遇到原始字符串中包含)"
的时候会导致不能将)
作为结束的分割符,这个时候一个非空的tag
会很有用:
std::string my_string = R"foo(This contains quoted parens "()")foo";
Conclusion
raw string literals
肯定不是我们大多数人的日常工具,但是有的时候善用这种新的语言功能会增加代码的可读性。因此下次当您试图搞清楚是否需要\\\\
或者\\\\\\\\
的时候,请尝试使用raw string literal
替换。你的读者会感谢你,即使这样,正则表达式仍然很难。
R"regexp((?:"(?:\\\\"|[^"])*"|'(?:\\\\'|[^'])*'))regexp"
以上是关于Tip of the Week #64: Raw String Literals的主要内容,如果未能解决你的问题,请参考以下文章
Tip of the Week #24: Copies, Abbrv
Tip of the Week #59: Joining Tuples
Tip of the Week #11: Return Policy
Tip of the Week #36: New Join API