正则表达式去除特定重复字符

15
我想在C#中创建一个正则表达式,如果特定字符重复并且不是字符串的最后一个字符,则删除它。
示例:
"a--b-c-" => "a-b-c"
"-a-b--c" => "a-b-c"
"--a--b--c--" => "a-b-c"

我不想让“-”字符重复出现,也不想它成为字符串的第一个或最后一个字符。我如何编写正则表达式来实现这个要求?

5个回答

26

最简单的方法可能是分两步来完成。首先,将一个或多个连字符“-”替换为一个单一的连字符“-”,然后删除任何前导/尾随的“-”。

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

var finalString = reducedString.Trim('-');

1
只是提供信息,Trim() 接受 "params",所以你只需要 .Trim('-') - John Rasch
这很糟糕。不要使用它。 - jaxxbo
@jaxxbo - 你能详细说明一下原因吗? - KeithS
@KeithS,使用的inputstring是“flower..plant.json”,替换“.+”后,最终字符串为空。它只对“-”有效,很奇怪。 - jaxxbo
1
句点字符在正则表达式中具有特殊含义,它匹配字符串中的任何单个字符。要特别匹配句点,您必须对其进行转义:"\.+"。但这并不是 OP 的情况;他想要删除在正则表达式模式中没有特殊含义的破折号。 - KeithS
显示剩余2条评论

8
针对这个特定问题,我可能不会使用正则表达式。相反,我可能会使用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");
        }
    }
}

1
创意解决方案,我更喜欢这种方法而不是正则表达式。 - Stofke

3
string tidyText = Regex.Replace(originalText, "^-+|(?<=-)-+|-+$", "");

这会删除开头和结尾的破折号吗?我不认为会。 - Stofke
@LukeH和Brad Christie:我看到它也删除了两端的破折号,但我不明白为什么。你们能解释一下吗? - Stofke
@Stofke - 我来晚了,但如果你还在疑惑:^-+-+$子句将匹配字符串的开头和结尾处的连字符。 - Justin Morgan

1

我知道你要求正则表达式,但是当你需要更改或重新阅读代码时,大多数人会选择重写它,因为这比重新学习代码要快。使用内置的字符串方法编写两行代码将比以后重新阅读正则表达式容易得多。在某些情况下,这也更快。

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

1
这个很接近,但是它会将 --a-b---c- 转化为 a-b--c - Justin Morgan

0

这可能更容易实现,而不需要使用正则表达式。可以尝试以下代码(未经测试):

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的答案,以获取基于正则表达式的解决方案。 - mellamokb
我理解你的思路...但我喜欢更短的代码 :) - Dismissile

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接