【问题标题】:Using regex.replace() to add to ", and "to the third to last comma in a string使用 regex.replace() 添加到 \" 和 \" 到字符串中倒数第三个逗号
【发布时间】:2023-01-04 02:27:40
【问题描述】:

我的代码中有两种情况:

  1. 仅包含名称且最后一项没有名称的字符串(", CPA, CFA")。例如,“约翰、简、乔”然后我使用下面的代码将最后一个逗号替换为 and 所以我得到“约翰、简和乔”
  2. 由姓名和末尾的 CPA/CFA 名称(", CPA, CFA")组成的字符串,例如“John, Jan, Joe, CPA, CFA”.在这种情况下,我需要将第三个到末尾的逗号替换为 and 以获取“John、Jan 和 Joe,CPA,CFA”.我只需要处理倒数第三个逗号的情况。我会注意到这些只是示例字符串,实际上它可以包含更多名称(即,它可以是“jake、jan、joe、john、jessie”),但最终我只是检查姓氏是否有名称(额外的逗号),如果有,它应该通过仅添加和替换来说明它倒数第三个逗号。

    我的目标是将 and 正确添加到逗号分隔列表中的最后一项,以遵循标准的英语惯例。最后一项的指定逗号脱离了我用来添加最后一项并替换逗号的正则表达式。

    我的代码:

    if(str1.EndsWith(", CPA, CFA"))
    {
           //need to figure out
    }
    else
    {
            Regex.Replace(str1, ", ([^,]+)$", " and $1");
    }
    

【问题讨论】:

  • 您如何构建“结束”条件?
  • 我想你可以对两者使用完全相同的正则表达式。但是,在 CPA 案例中,您只需在末尾附加该修复字符串。
  • 如果我需要向下移动到倒数第三个逗号,我将如何使用相同的正则表达式?

标签: c# .net regex asp.net-core .net-core


【解决方案1】:

您可以使用带有 2 个捕获组的模式捕获第一个逗号并匹配第二个逗号

替换使用 2 组 $1 and $2

([^s,]+),s*([^s,]+(?:, CPA, CFA)?)$

模式匹配:

  • ([^s,]+)捕捉第 1 组, 匹配 1+ 个非空白字符和一个逗号

  • ,s* 匹配逗号和可选的空白字符

  • (捕捉第 2 组

    • [^s,]+ 匹配除空白字符或逗号以外的 1+ 个字符
    • (?:, CPA, CFA)? 可选择匹配, CPA, CFA
  • )关闭第2组

  • $字符串结尾

Regex demo | C# demo

例子

string pattern = @"([^s,]+),s*([^s,]+(?:, CPA, CFA)?)$";
string input = "John, Jan, Joe
John, Jan, Joe, CPA, CFA
jake, jan, joe, john, jessie, jack, jones";
Console.WriteLine(Regex.Replace(input, pattern, @"$1 and $2", RegexOptions.Multiline));

输出

John, Jan and Joe
John, Jan and Joe, CPA, CFA
jake, jan, joe, john, jessie, jack and jones

【讨论】:

  • 这是一种有趣的方法,但是我已经编辑了我的问题,因为它可能不够清楚。基本上我不知道字符串中有多少个名字。所以真的要有正确的英语,我只需要检查最后一个条目是否有指定或不考虑额外的逗号来添加和。因此,如果我向其中添加五个名称,那么运行您的代码,然后将 and 添加到第三个元素,而不是最后一个元素,这才是我最终关心的。
  • @qiuzman 像这样吗? ([^s,]+,)(s*(?:[^s,]+(?:, CPA, CFA)?$)) regex101.com/r/BYUUs0/1
  • 您能否使用 regex.replace 函数将其添加到上面的答案中以使其完整,我将重新选择为所选答案。
  • @qiuzman 我已经更新了答案并稍微调整了模式。
  • @Thefourthbird John, Jan, Joe 结果应该是John, Jan and Joe
【解决方案2】:

不使用Regex也可以使用下面的代码

//string input = "John, Jan, Joe, CPA, CFA";
string input = "John, Jan, Joe";
var result = input.Select((b, i) => b.Equals(',') ? i : -1).Where(i => i != -1).ToList();

if(input.EndsWith(", CFA"))
     input=input.Replace(input.Substring(0,result[result.Count()-3] +2), input.Substring(0, result[result.Count()-3]+2) + "and ");
else
     input = input.Replace(input.Substring(0, result[result.Count()-1] +1), input.Substring(0, result[result.Count()-1]) + " and ");

Console.WriteLine(input); 

如果string input = "John, Jan, Joe, CPA, CFA"

结果:“John, Jan, and Joe, CPA, CFA”(显然,您添加了一个额外的逗号)

如果string input = "John, Jan, Joe"

结果:约翰、简和乔

【讨论】:

  • 如果列表中不止这些人,则计数可能不是 4。所以您的代码看起来只有在您知道我不知道的人数的情况下才能在这种情况下工作。这就是为什么我使用 EndsWith() 来检查最后一个是否包括指定 CPA、CFA
  • @qiuzman 你没有完全解释这个问题。你刚才说我有两种情况。我据此回答。但是算法是正确的。我编辑答案...
  • 现在要对此进行测试,但我已经在问题中添加了警告作为编辑,所以我为没有明确说明而道歉。
  • 使用您的代码并添加更多名称,它的行为与所提到的不同。这是您在此示例中运行的代码: dotnetfiddle.net/JMO4ug。在提供的代码示例中,如果我添加了其他名称,它仍然会在第三个元素之后添加一个 and 。它需要是动态的,因为我不知道计数。
  • @qiuzman 您编辑了问题。我重新编辑了答案:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-09
  • 1970-01-01
  • 2011-11-25
  • 2022-08-11
相关资源
最近更新 更多