我需要移除字符串的最后一个字符,而在我的情况下这个字符是逗号(","):
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();
foreach(line, content.splitLines(keepTerminator.no)) { ... }
- Panke通常情况下,字符串处理取决于您对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
"last char"实际上指的是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
将反转迭代顺序回到正常状态,但现在已经删除了最后一个元素。import std.range, std.uni, std.stdio;
auto range = "abcde".byGrapheme.retro.drop(1).retro();
writeln(range);
很遗憾,由于Phobos中的一个漏洞,似乎目前不支持这种特定模式。我已经就此问题创建了一个Issue: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 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;
}
}
auto offset = str.lastIndexOf("thing-to-chop-off"); if(offset >= 0) str = str[0 .. offset];
。 - Adam D. Ruppe