d转义控制符
原创
©著作权归作者所有:来自51CTO博客作者fqbqrr的原创作品,请联系作者获取转载授权,否则将追究法律责任
如何格式化
串,来显示打印\n
和\t
等?
r"ab\n"
//或
`ab\n`
//或
"abc\\ndef\\tghi"
但如果是运行时
串,可能必须用std.regex.replaceAll
等来手动
转义字符.或用管道
手动替换:
string myString = ...;
string escapedStr = myString
.chunks(1)
.map!(c => (c == "\n") ? "\\n" :
(c == "\r") ? "\\r" :
(c == "\t") ? "\\t" :
c)
.joiner
.array;
这样:
string a = r"ab\n";
writeln(escape(a)); // => ab\n
//我这样
string escapedStr = myString
.replace("\n",`\n`)
.replace("\r",`\r`)
.replace("\t",`\t`);
或这样:
auto escapedStr = appender!string;
for(c;myString) {
switch(c) {
case '\n':
escapedStr.put("\\n");
case '\r':
escapedStr.put("\\r");
...
default:
escapedStr.put(c);
}
}
最简单
的是这样:
import std.conv;
string str = `Hello "World"
line 2`;
writeln([str].text[2..$-2]); // Hello \"World\"\nline 2
这利用了std.format
转义了串数组
中字符.我们创建str
为唯一元素
的数组,并转换它为文本.如果没有[2..$-2]
切片,输出将是["Hello\"World\"\nline2"]
.
一个稍微更有效的实现是:
string escape(string s)
{
import std.array :;
import std.format :, formatValue;
FormatSpec!char f;
auto w = appender!string;
w.reserve(s.length);
formatValue(w, [s], f);
return w[][2 .. $ - 2];
}
//反函数
string unescape(string s)
{
import std.format :, unformatValue;
FormatSpec!char f;
string str = `["` ~ s ~ `"]`;
return unformatValue!(string[])(str, f)[0];
}
escape()
和unescape()
应为std.format
部分,然后,可直接用std.format.internal.write.formatElement
来避免转换至数组.
没有分配.如下需要1符
缓冲区来避免发送包围
的引号.
struct EscapedString
{
string[1] str;
this(string str) @nogc pure nothrow @safe { this.str[0] = str; }
void toString(Out)(auto ref Out output)
{
import std.format;
import std.range;
char buf; // 0xff => 空的, 0x0, 空的,但不是第1个
void putter(const(char)[] data) {
if(!data.length) return;
if(buf != 0xff)
{
if(buf)
put(output, buf);
}
else
// 跳过第1个 "
data = data[1 .. $];
if(!data.length){
buf = 0;
return;
}
put(output, data[0 .. $-1]);
buf = data[$-1];
}
scope x = &putter;
formattedWrite(x, "%(%s%)", str[]);
}
}
从格式
中公开转义功能
会很好,就不需要这种技巧了.
自定义包装串.
struct String {
string str;
alias str this;
import std.format, std.string;
void toString(scope void delegate(const(char)[]) sink,FormatSpec!char fmt)const
{
auto arr = str.lineSplitter;
if(fmt.spec == 'n') {
sink.formattedWrite("%-(%s\\n%)", arr);
} else sink.formattedWrite("%s", str);
}
} unittest {
import std.stdio;
auto str = `这是
串`;
String Str; // 简单构造器
Str = str; // 直接赋值
Str.writefln!"%n"; // "这是\n串"
Str.writefln!"%s"; /*
这是
串
*/
}