获取子字符串-某些字符之前的所有内容


124

我正在尝试找出在字符串中的-字符之前获取所有内容的最佳方法。下面是一些示例字符串。字符串之前的长度-可以不同,可以是任意长度

223232-1.jpg
443-2.jpg
34443553-5.jpg

所以我需要从0开始索引到-之前的值。因此,子字符串将变为223232、443和34443553

Answers:


144

.Net小提琴示例

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("223232-1.jpg".GetUntilOrEmpty());
        Console.WriteLine("443-2.jpg".GetUntilOrEmpty());
        Console.WriteLine("34443553-5.jpg".GetUntilOrEmpty());

        Console.ReadKey();
    }
}

static class Helper
{
    public static string GetUntilOrEmpty(this string text, string stopAt = "-")
    {
        if (!String.IsNullOrWhiteSpace(text))
        {
            int charLocation = text.IndexOf(stopAt, StringComparison.Ordinal);

            if (charLocation > 0)
            {
                return text.Substring(0, charLocation);
            }
        }

        return String.Empty;
    }
}

结果:

223232
443
34443553
344

34

2
请帮他们一个忙,并假设他计划使用此功能来添加错误检查以及:)
乔什(Josh)2009年

谢谢,我很接近这一点,但是很好奇是否有人会使用除此组合以外的其他方法。但是,是的,这很好用,而且还很短。
PositiveGuy

14
如果您想要string result = source.Substring(0, Math.Max(source.IndexOf('-'), 0))
单线但又

2
当知道(如此处)字符串的长度严格超过时,s.Substring(0, n)可以使用代替。s.Remove(n)sn
2014年

@LukeH如果在您的示例中IndexOf返回-1,那么将返回一个空字符串,不是吗?
暗恋

124

使用分割功能。

static void Main(string[] args)
{
    string s = "223232-1.jpg";
    Console.WriteLine(s.Split('-')[0]);
    s = "443-2.jpg";
    Console.WriteLine(s.Split('-')[0]);
    s = "34443553-5.jpg";
    Console.WriteLine(s.Split('-')[0]);

Console.ReadKey();
}

如果您的字符串没有a,-那么您将获得整个字符串。


4
如果您有多个连字符,则数组中会包含多个元素。
詹姆斯·邓恩

2
的确,詹姆斯,所以只有在您期望仅使用一个连字符的情况下,这才是解决方案。我想您可以使用Linq方法(例如“跳过”和“聚合”)来获得所需的内容,但是与已经提出的方法相比,您可以获得更多的代码。这完全取决于您对传入数据的了解程度。
多米尼克·克罗宁

7
几年后,我才意识到,我太快地承认詹姆斯的观点。该问题询问如何在某个字符之前找到字符串。因此,该字符的其他实例无关紧要,并且采用[0]将“有效”。当然,这仍然取决于我们对传入数据的信任程度。如果根本没有“-”怎么办?
多米尼克·克罗宁

1
我认为@JamesDunne的要点是,通过拆分为数组,您正在创建一堆不必要的字符串-不必要的垃圾。
暗恋

1
我不会担心“不必要的垃圾”。用这种方式创建的任何额外的字符串将立即无法访问,因此将在第0代中收集,这确实是非常低的开销。垃圾收集器的设计明确旨在允许大量使用短命项目,而几乎不会产生任何费用。
多米尼克·克罗宁

65
String str = "223232-1.jpg"
int index = str.IndexOf('-');
if(index > 0) {
    return str.Substring(0, index)
}

upvote,因为我需要知道分隔符的索引
Piero Alberto

3
这实际上与Fredou给出的答案相同(当前为最高答案),只是它省略了未找到匹配项的情况。
多米尼克·克罗宁

7

自从该线程启动以来,情况有所发展。

现在,您可以使用

string.Concat(s.TakeWhile((c) => c != '-'));

如何将性能与明显的IndexOf和Substring组合进行比较?我假设它将每个字符附加到StringBuilder,然后在末尾生成一个字符串。还混入了两个函数调用。如果Substring可以简单地将-1作为“ length”参数(表示“ string end”),那就太好了。
暗恋

1
效率更差。正如您所说,它使用字符串生成器,并且检查了代码之后似乎在每个字符上调用ToString。如果您要查找多个字符,则更加清楚,因为您可以轻松地重写lambda。
安东尼·威瑟

4

一种方法是与String.Substring一起使用String.IndexOf

int index = str.IndexOf('-');
string sub;
if (index >= 0)
{
    sub = str.Substring(0, index);
}
else
{
    sub = ... // handle strings without the dash
}

从位置0开始,返回直到破折号(但不包括破折号)的所有文本。


如果索引<= 0,则应该只返回string.empty。
不退款

5
@NRNR:如果你这么说。该OP知道业务需求,而不是你或I.
迈克尔Petrotta

0

建立在BrainCore的答案上:

    int index = 0;   
    str = "223232-1.jpg";

    //Assuming we trust str isn't null 
    if (str.Contains('-') == "true")
    {
      int index = str.IndexOf('-');
    }

    if(index > 0) {
        return str.Substring(0, index);
    }
    else {
       return str;
    }

0

您可以为此使用正则表达式,但是最好避免输入字符串与正则表达式不匹配时出现额外的异常。

首先,要避免转义到正则表达式模式的额外麻烦-我们可以为此使用函数:

String reStrEnding = Regex.Escape("-");

我知道这不会做任何事情-因为“-”与相同Regex.Escape("=") == "=",但是例如character是会有所不同@"\"

然后,我们需要从字符串的乞求到字符串结尾匹配,或者如果找不到结尾,则进行匹配-然后不匹配。(空字符串)

Regex re = new Regex("^(.*?)" + reStrEnding);

如果您的应用程序对性能至关重要-如果不是,则为新的Regex单独一行-您可以将所有内容放在一行中。

最后匹配字符串并提取匹配的模式:

String matched = re.Match(str).Groups[1].ToString();

之后,您可以编写单独的函数(如在另一个答案中所做的那样),也可以编写内联lambda函数。我现在使用两种表示法-内联lambda函数(不允许默认参数)或单独的函数调用编写。

using System;
using System.Text.RegularExpressions;

static class Helper
{
    public static string GetUntilOrEmpty(this string text, string stopAt = "-")
    {
        return new Regex("^(.*?)" + Regex.Escape(stopAt)).Match(text).Groups[1].Value;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Regex re = new Regex("^(.*?)-");
        Func<String, String> untilSlash = (s) => { return re.Match(s).Groups[1].ToString(); };

        Console.WriteLine(untilSlash("223232-1.jpg"));
        Console.WriteLine(untilSlash("443-2.jpg"));
        Console.WriteLine(untilSlash("34443553-5.jpg"));
        Console.WriteLine(untilSlash("noEnding(will result in empty string)"));
        Console.WriteLine(untilSlash(""));
        // Throws exception: Console.WriteLine(untilSlash(null));

        Console.WriteLine("443-2.jpg".GetUntilOrEmpty());
    }
}

顺便说一句-将正则表达式模式更改为"^(.*?)(-|$)"将允许拾取直到"-"模式或未找到模式-拾取所有内容直到字符串结尾。


0

LINQy方式

String.Concat(“ 223232-1.jpg” .TakeWhile(c => c!='-'))

(但是,您确实需要测试null;)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.