【问题标题】:using Regex to iterate over a string and search for 3 consecutive hyphens and replace it with [space][hyphen][space]使用 Regex 遍历字符串并搜索 3 个连续的连字符并将其替换为 [space][hyphen][space]
【发布时间】:2017-10-13 02:41:02
【问题描述】:

我目前有一个返回时看起来像这样的字符串:

//This is the url string
// the-great-debate---toilet-paper-over-or-under-the-roll

string name = string.Format("{0}",url);
name = Regex.Replace(name, "-", " ");

当我执行以下正则表达式操作时,它变成了这样:

 the great debate  toilet paper over or under the roll

但是,就像我在问题中提到的那样,我希望能够将正则表达式应用于 url 字符串,以便获得以下输出:-

 the great debate - toilet paper over or under the roll

我非常感谢任何帮助。

[编辑] 然而,并不是所有的字符串都是这样的,其中一些只有一个连字符,所以上述方法有效

 world-water-day-2016

它变成了

 world water day 2016

但是对于这个:

the-great-debate---toilet-paper-over-or-under-the-roll

我需要一种方法来检查字符串是否有 3 个连字符,而不是用 [space][hyphen][space] 替换这 3 个连字符。而不是用空格替换单词之间所有剩余的单个连字符。

【问题讨论】:

  • Without regex: url.Replace("---", "[ \uFFFD ]").Replace("-", " ").Replace("[ \uFFFD ]", " - ")
  • 啊,错过了你也想要单词之间的连字符。
  • 您必须处理 2 个连字符还是超过 3 个连字符?
  • 一个正则表达式:Regex.Replace(s, @"-(-)-|-", m => m.Groups[1].Success ? " - " : " ").
  • 好的,所以一个 url 返回一个像这样的字符串:world-water-day-2016the-great-debate---toilet-paper-over-or-under

标签: c# regex


【解决方案1】:

首先,对于这类问题,总是有一个非常幼稚的解决方案:将上下文中的特定匹配项替换为当前环境中通常不使用的一些字符,并且在替换通用子字符串后,您可以替换临时子字符串除了必要的例外。

var name = url.Replace("---", "[ \uFFFD ]").Replace("-", " ").Replace("[ \uFFFD ]", " - ");

您还可以使用基于正则表达式的替换来匹配捕获它的 3 连字符子字符串,或者仅匹配单个连字符,然后检查第 1 组是否在匹配评估器中匹配(Regex.Replace 的第三个参数可以是匹配评估器方法)。

看起来像

var name = Regex.Replace(url, @"(---)|-", m => m.Groups[1].Success ? " - " : " ");

请参阅C# demo

因此,当(---) 部分匹配时,3 个连字符被放入第 1 组,.Success 属性设置为true。因此,m => m.Groups[1].Success ? " - " : " " 将 3 个连字符替换为空格+-+空格,并将 1 个连字符(实际上可能是 2 个连续连字符中的 1 个)替换为空格。

【讨论】:

  • 很好的解释!惊人的 !谢谢!
【解决方案2】:

这是一个使用 LINQ 而不是正则表达式的解决方案:

var str = "the-great-debate---toilet-paper-over-or-under-the-roll";
var result = str.Split(new string[] {"---"}, StringSplitOptions.None)
                .Select(s => s.Replace("-", " "))
                .Aggregate((c,n) => $"{c} - {n}");

// result = "the great debate - toilet paper over or under the roll"

根据--- 拆分字符串,然后从每个子字符串中删除连字符,然后将它们重新连接在一起。

【讨论】:

    【解决方案3】:

    简单的方法:

    name = Regex.Replace(name, "\b-|-\b", " ");
    

    炫耀方式:

    name = Regex.Replace(name, "(\b)?-(?(1)|\b)", " ");
    

    【讨论】:

    • 我试过了,但不知何故根本没有删除连字符。
    • 尝试双重转义?它绝对适用于您提供的示例。见regex101.com/r/aStQ7L/2
    • ` \ ` 是一个 C# 转义字符,所以\b 代表退格字符。如果您不想使用 C# 转义序列,则应以 @" 开头字符串,或使用 \` instead of `
    • @JacobKrall 感谢您阐明为什么它不起作用。
    • @CAustin 感谢您以不同的方式启发我。
    猜你喜欢
    • 1970-01-01
    • 2019-04-24
    • 1970-01-01
    • 2021-06-19
    • 2018-07-06
    • 2020-01-06
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    相关资源
    最近更新 更多