D:如何删除字符串中的最后一个字符?

问题描述 投票:0回答:6

我需要删除字符串中的最后一个字符,在我的例子中它是逗号(“,”):

foreach(line; fcontent.splitLines)
{
    string row = line.split.map!(a=>format("'%s', ", a)).join;
    writeln(row.chop.chop);
}

我只找到一种方法——调用chop两次。首先删除

\r\n
,然后删除最后一个字符。

还有什么更好的办法吗?

string d
6个回答
4
投票
import std.array;
if (!row.empty)
    row.popBack();

2
投票

由于字符串处理通常会发生这种情况,因此这取决于您对 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


0
投票

注意:更新了我的答案,使其更加简洁,并删除了“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; 
} 

0
投票
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;
}

0
投票

我使用切片的实现:

string line = "Some value,";
string choppedLine = line[0..$-1]; // choppedLine has value "Some value".

-1
投票

你看一下,我用这个扩展方法来替换任何最后一个字符或子字符串,例如:

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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.