D:从第二次出现的字符拆分字符串

D: Split string from the second occurrence of the character

我需要在第二次出现(“-”)之前拆分字符串。

示例:s1-qwe-123

需要获得:s1-qwe

最佳做法是什么?

嗯,谢谢,但遇到一些文件结构如下的情况: s1-123。我需要从他们那里得到:s1.

有没有什么办法可以在这种情况下用split process做变体?

有很多方法可以实现这一点,我将介绍两种。

首先是用“-”分割整个字符串,然后连接前两个元素:

import std.stdio, std.string;
"s1-qwe-123".split("-")[0 .. 2]
            .join("-")
            .writeln;    // -> "s1-qwe"

这很简单,但效率可能不够高,因为必须读取整个字符串。我建议的另一种方法是使用正则表达式,因为有一个 matchFirst 函数只读取字符串直到表达式的第一次出现。

import std.stdio, std.regex;
"s1-qwe-123".matchFirst("[^-]+-[^-]+")[0]
            .writeln;  // -> "s1-qwe"

如果你想让它真的快,你可以使用编译时正则表达式:

import std.stdio, std.regex;
"s1-qwe-123".matchFirst(ctRegex!("[^-]+-[^-]+"))[0]
            .writeln;  // -> "s1-qwe"

您可以将其拆分并再次合并。

string line = "s1-qwe-123";
string interestedBit = line.split("-")[0..2].join("-");

或者通过字符循环:

int idx;
bool found;
string line = "s1-qwe-123";
for(idx = 0; idx < line.length; ++idx){
    if(line[idx] == '-')
        if(found)
            break;
        else
            found = true;
}
auto interestedBit = line[0..idx];

我原来的回答是完全错误的,因为我看错了问题。这是一个正确答案,它与其他答案中已经建议的 split 解决方案略有不同:

import std.algorithm : splitter; 
import std.array : join;
import std.range : take;
auto res = "s1-qwe-123".splitter("-").take(2).join('-');
assert(res == "s1-qwe");

使用 splitter 优于 split 的优点是惰性求值。这应该只走到第二个'-',而不是进一步。

int saw;
auto s = "s1-qwe-123".findSplitBefore!(c => c == '-' && saw++ > 0)[0];