我需要删除字符串中的最后一个字符,在我的例子中它是逗号(“,”):
foreach(line; fcontent.splitLines)
{
string row = line.split.map!(a=>format("'%s', ", a)).join;
writeln(row.chop.chop);
}
我只找到一种方法——调用chop两次。首先删除
\r\n
,然后删除最后一个字符。
还有什么更好的办法吗?
import std.array;
if (!row.empty)
row.popBack();
由于字符串处理通常会发生这种情况,因此这取决于您对 Unicode 的关心程度。
如果您只使用 ASCII,则非常简单:
import std.encoding;
// no "nice" ASCII literals, D really encourages Unicode
auto str1 = cast(AsciiString) "abcde";
str1 = str1[0 .. $-1]; // get slice of everything but last byte
auto str2 = cast(AsciiString) "abcde\n\r";
str2 = str2[0 .. $-3]; // same principle
“最后一个字符”实际上意味着 unicode 代码点(http://unicode.org/glossary/#code_point),它变得有点复杂。简单的方法就是依靠D自动解码和算法:
import std.range, std.stdio;
auto range = "кириллица".retro.drop(1).retro();
writeln(range);
这里
retro
(http://dlang.org/phobos/std_range.html#.retro)是一个惰性反向迭代函数。它接受任何范围(unicode 字符串是有效范围)并返回能够向后迭代它的包装器。
drop
(http://dlang.org/phobos/std_range.html#.drop) 只是弹出一个范围元素并忽略它。再次调用 retro
会将迭代顺序反转回正常状态,但现在会删除最后一个元素。
它与 ASCII 版本不同的原因是 Unicode 的性质(特别是 D 默认的 UTF-8) - 它不允许随机访问任何代码点。实际上,您需要将它们一一解码才能获得任何所需的索引。幸运的是,D 会为您处理所有解码,并将其隐藏在方便的范围接口后面。
对于那些想要更多 Unicode 正确性的人,应该可以对字素进行操作 (http://unicode.org/glossary/#grapheme):
import std.range, std.uni, std.stdio;
auto range = "abcde".byGrapheme.retro.drop(1).retro();
writeln(range);
遗憾的是,由于 Phobos 中的错误,目前似乎不支持此特定模式。我创建了一个关于它的问题:https://issues.dlang.org/show_bug.cgi?id=14394
注意:更新了我的答案,使其更加简洁,并删除了“map!”中的 lambda 函数因为它有点丑。
import std.algorithm, std.stdio;
import std.string;
void main(){
string fcontent = "I am a test\nFile\nwith some,\nCommas here and\nthere,\n";
auto data = fcontent
.splitLines
.map!(a => a.replaceLast(","))
.join("\n");
writefln("%s", data);
}
auto replaceLast(string line, string toReplace){
auto o = line.lastIndexOf(toReplace);
return o >= 0 ? line[0..o] : line;
}
module main;
import std.stdio : writeln;
import std.string : lineSplitter, join;
import std.algorithm : map, splitter, each;
enum fcontent = "some text\r\nnext line\r\n";
void main()
{
fcontent.lineSplitter.map!(a=>a.splitter(' ')
.map!(b=>"'" ~ b ~ "'")
.join(", "))
.each!writeln;
}
我使用切片的实现:
string line = "Some value,";
string choppedLine = line[0..$-1]; // choppedLine has value "Some value".
你看一下,我用这个扩展方法来替换任何最后一个字符或子字符串,例如:
string testStr = "Happy holiday!";<br>
Console.Write(testStr.ReplaceVeryLast("holiday!", "Easter!"));
public static class StringExtensions
{
public static string ReplaceVeryLast(this string sStr, string sSearch, string sReplace = "")
{
int pos = 0;
sStr = sStr.Trim();
do
{
pos = sStr.LastIndexOf(sSearch, StringComparison.CurrentCultureIgnoreCase);
if (pos >= 0 && pos + sSearch.Length == sStr.Length)
sStr = sStr.Substring(0, pos) + sReplace;
} while (pos == (sStr.Length - sSearch.Length + 1));
return sStr;
}
}