【问题标题】:C# Replace Everything before the first SpaceC# 替换第一个空格之前的所有内容
【发布时间】:2016-02-06 12:31:23
【问题描述】:

我需要在第一次出现空格之前删除字符串中的所有内容。

  1. 每个字符串都以数字开头,后跟一个空格
  2. 替换数字和空格,从而使字符串的其余部分保持完整

例如:

22 印度的猫

4 殿下

562 吃土豆

第二个冰箱里有 42 块饼干

2564 尼亚加拉大瀑布下午 2 点

我只需要:

印度的猫

王子殿下

吃土豆

第二个冰箱里的饼干

下午 2 点的尼亚加拉大瀑布

基本上去掉第一个空格前的每个数字,包括第一个空格。

我试过了:

foreach (string line in lines)
{
       string newline = line.Trim().Remove(0, line.IndexOf(' ') + 1);
}

这适用于 10 以下的数字。在达到 2 位数字后,它就不能正常工作了。

我应该如何更改我的代码?

【问题讨论】:

  • 地球人,很多人已经回答了你最初的问题。您现在评论了一个附加问题。这不是 SO 的工作方式。如果您还有其他问题,请打开另一个问题。
  • 别忘了给那些有帮助的人点赞。
  • 如果已知输入采用上述格式,则在这种情况下使用正则表达式是,IMO,矫枉过正:string.Concat(str.TrimStart().SkipWhile(char.IsNumber).Skip(1))。每次必须更改此代码时,问问自己是否想在 Google 上搜索 \p{Zs} 的含义...

标签: c# regex replace


【解决方案1】:

如果要确保只匹配字符串开头的数字,可以使用以下正则表达式:

^\d+\p{Zs}

demo

声明如下:

public static readonly Regex rx = new Regex(@"^\d+\p{Zs}", RegexOptions.Compiled);

^\d+\p{Zs} 正则表达式表示:字符串开头的一位或多位数字后跟 1 个空格。

然后像这样使用它

string newline = rx.Replace(line, string.Empty);

编辑:为确保line 没有前导空格,我们可以添加.Trim() 将其剥离:

Regex rx = new Regex(@"^\d+\p{Zs}", RegexOptions.Compiled);
string newline = rx.Replace(line.Trim(), string.Empty);

【讨论】:

  • 这修复了它!太感谢了!我也添加了一些细微的变化。我添加了 line.Trim() 让它工作/谢谢!
  • 啊哈,如果您只需要删除 前导 空格,您仍然可以使用^\p{Zs}*\d+\p{Zs},但如果您仍然需要从@987654330 末尾修剪空格@,你真的可以使用Trim()
【解决方案2】:

我知道您已经找到解决问题的方法。但我将解释为什么你的代码一开始就不起作用。

您的数据有多余的空格,这就是您修剪它的原因:line.Trim()。但真正的问题在于以下语句:

string newline = line.Trim().Remove(0, line.IndexOf(' ') + 1);

您正在假设操作的顺序以及string 数据类型不是immutable 的事实。当Trim() 函数的操作完成时,它会返回一个全新的字符串,用于Remove() 操作。但是IndexOf()函数是在原始数据行上完成的。

所以正确的代码行如下:

foreach (string line in lines)
{
    // trim the line first
    var temp = line.Trim();

    // now perform all operation on the new temporary string
    string newline = temp.Remove(0, temp.IndexOf(' ') + 1);

    // debugging purpose
    Console.WriteLine(newline);
}

【讨论】:

    【解决方案3】:

    另一种解决方案:

    var lines = new string[]
        {
            "22 The cats of India",
            "4 Royal Highness",
            "562 Eating Potatoes",
            "42 Biscuits in the 2nd fridge",
            "2564 Niagara Falls at 2 PM"
        };
    
    foreach (var line in lines)
    {
        var newLine = string.Join(" ", line.Split(' ').Skip(1));
    }
    

    【讨论】:

    • 是的,它会,但问题是关于一个特定的输入 :) “每个字符串都以数字开头,后跟一个空格”
    • 输入质量不能太确定(我在本地化行业工作):)。
    • 我完全同意你的观点:)
    【解决方案4】:

    像这样使用正则表达式:

    string newline = Regex.Replace(line, @"^\s*\d+\s*", "");
    

    这将只删除数字,而不是第一个空格之前的其他文本。

    【讨论】:

    • 编辑:如果我需要第一个空格后的所有数字怎么办。我只需要替换数字和第一个空格
    • @Earthling 为什么不试试提供的回复?我的正则表达式锚定在字符串的开头,因此它只在开头使用数字!
    • 它也会匹配字符串开头的空格,如果后面有一个没有空格的数字也会匹配。
    • @WiktorStribiżew 没错,我认为这是一种行为,因为原始示例有一个 Trim() 调用。对于无空格的情况,也没有明确指定“第一个空格之前的任何数字”;我假设“任何数字”是必不可少的部分,结果字符串应该被修剪掉。
    【解决方案5】:

    这就是你要找的东西

    foreach (string line in lines)
    {
           string newline = line.Replace(line.Split(new Char[]{' '})[0] + ' ',string.Empty);
    }
    

    更新

    string search=line.Split(new Char[]{' '})[0];
    int pos=line.indexOf(search);
    string newline = line.Substring(0, pos) + string.Empty + line.Substring(pos + search.Length);
    

    完整代码

    using System;
    
    public class Program
    {
        public static void Main()
        {
            var lines = new string[]
            {
                "22 The cats of India",
                "4 Royal Highness",
                "562 Eating Potatoes",
                "42 Biscuits in the 2nd fridge",
                "2 Niagara Falls at 2 PM"
            };
            foreach(string line in lines){
                string search=line.Split(new Char[]{' '})[0];
                int pos=line.IndexOf(search);
                string newline = line.Substring(0, pos) + string.Empty + line.Substring(pos + search.Length);
                Console.WriteLine(newline);
            }
        }
    }
    

    【讨论】:

    • 不确定,但似乎这段代码无法编译,似乎很难理解,如果稍后在字符串中找到第二次出现的数字,它也会将其清除。
    • 这段代码运行良好,我已经更新了代码。添加Split 而不是split。它在小提琴上工作正常。
    • 如果你有“1 Banana 1 Fruit”作为字符串,结果将是“Banana Fruit”而不是 OP 要求的“Banana 1 Fruit”。
    • @Lucero @Earthling 我已经更新了我的代码并添加了一个完整的代码,它现在可以正常工作了。1 Banana 1 Fruit 将是 Banana 1 Fruit
    • 好吧,除了非常效率低下之外,它仍然不仅会删除数字,还会删除第一个空格之前的任何内容。还有一些边缘情况并没有真正起作用 - 请参阅dotnetfiddle.net/JTUvRF ;)
    猜你喜欢
    • 2021-10-15
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    • 2014-08-03
    • 1970-01-01
    • 2012-05-19
    • 1970-01-01
    相关资源
    最近更新 更多