【问题标题】:Regex to remove a specific repeated character正则表达式删除特定的重复字符
【发布时间】:2011-07-03 23:24:00
【问题描述】:

我想在 C# 中创建一个正则表达式,如果特定字符重复,则删除它,因此它不是字符串的最后一个字符。

例子:

"a--b-c-" => "a-b-c"
"-a-b--c" => "a-b-c"
"--a--b--c--" => "a-b-c"

我从不希望 - 重复,并且我从不希望它成为字符串的第一个或最后一个字符。我怎么能写一个正则表达式来做到这一点?

【问题讨论】:

    标签: c# regex


    【解决方案1】:

    可能最简单的方法是分两步完成。首先将每个出现的一个或多个“-”替换为单个“-”,然后修剪任何前导/尾随“-”。

    var reducedString = Regex.Replace(inputString, "-+", "-");
    
    var finalString = reducedString.Trim('-');
    

    【讨论】:

    • 仅供参考,Trim() 接受“参数”,所以您只需要.Trim('-')
    • 选择类甚至是必要的吗? ([]的)
    • 可能不是,但我知道 - 在一个字符范围内需要转义,而我不知道它是否在一个字符范围之外有特殊含义。
    • 我喜欢这个解决方案。谢谢!
    • 句号在正则表达式中有特殊含义;它匹配字符串中的任何单个字符。要专门匹配一个句点,您必须对其进行转义:"\.+"。那不是OP的情况。他想删除在正则表达式模式中没有特殊含义的破折号。
    【解决方案2】:

    对于这个特定的问题,我可能不会使用正则表达式。相反,我可能会使用String.SplitString.Join 的组合,这会更简单,而且可能更快:

    像这样:

    string.Join("-", s.Split(new char[] {'-'}, StringSplitOptions.RemoveEmptyEntries));
    

    通过测试:

    using System;
    class Program
    {
        static string RemoveDashes(string s)
        {
            return string.Join("-", s.Split(new char[] { '-' }, 
                                StringSplitOptions.RemoveEmptyEntries));
        }
        static void Main(string[] args)
        {
            Tuple<string, string>[] tests = new Tuple<string,string> [] 
            {
                new Tuple<string, string> ("a--b-c-", "a-b-c"),
                new Tuple<string, string> ("-a--b-c-", "a-b-c"),
                new Tuple<string, string> ("--a--b--c--", "a-b-c"),
            };
            foreach (var t in tests)
            {
                string s = RemoveDashes(t.Item1);
                Console.WriteLine("{3}: {0} => Expected: {1}, Actual: {2}", 
                            t.Item1, t.Item2, s, s == t.Item2 ? "PASS" : "FAIL");
            }
        }
    }
    

    【讨论】:

    • 创意解决方案,我实际上更喜欢这个而不是正则表达式
    【解决方案3】:
    string tidyText = Regex.Replace(originalText, "^-+|(?<=-)-+|-+$", "");
    

    【讨论】:

    • 这会删除开头和结尾的破折号吗?我不这么认为。
    • @LukeH & Brad Christie:我看到它确实删除了边缘的破折号,我只是不明白为什么。你能解释一下为什么会这样吗?
    • @Stofke - 我迟到了,但如果你仍然想知道:^-+-+$ 子句将匹配字符串开头和结尾的连字符字符串,分别。
    【解决方案4】:

    我知道您要求使用正则表达式,但第二次您必须更改或重新阅读该代码,大多数人只是重写它,因为它比重新学习代码的作用要快。使用内置字符串方法的 2 行将比重新阅读未来的正则表达式容易得多。在某些情况下它会更快。

            string text = "--a-b--c-";
            text = text.Replace( "--", "-" );
            text = text.Trim( '-' );
    

    【讨论】:

    • 这很接近,但它会将--a-b---c- 变成a-b--c
    【解决方案5】:

    如果没有正则表达式,这可能更容易实现。类似于以下内容(未经测试):

    string s = "--a--b--c--";
    string t = "";
    
    bool atStart = true;
    bool inHyphen = false;
    
    foreach (char c in s) {
        if (c != "-") {
            if (atStart) {
                atStart = false;
            } else if (inHyphen) {
                inHyphen = false;
                t += "-";
            }
            t += c;
        } else {
            inHyphen = true;
        }
    }
    

    【讨论】:

    • @Dismissile:我是一个实用主义者。对我来说,解决问题比关心它是如何完成的更重要。 编辑请参阅@KeithS 或@LukeH 对基于正则表达式的解决方案的回答。
    • 我理解你的思路...但我喜欢更短的代码:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-26
    • 2011-06-02
    • 1970-01-01
    相关资源
    最近更新 更多