【问题标题】:Regex - Conditional replace if captured group exists正则表达式 - 如果捕获的组存在,则进行条件替换
【发布时间】:2016-02-17 14:59:18
【问题描述】:

假设我有以下 2 个代表电话号码的字符串:

  1. 1112223333
  2. 11122233334

第一个用于普通电话号码(111) 222-3333,第二个用于带有分机号(111) 222-3333 ext 4的电话号码

所以我们知道电话号码始终是 10 位数字,可能是 11。如果是 11,那么我希望它使用第二个版本进行格式化。

我目前的正则表达式和替换如下:

正则表达式: (\d{3})(\d{3})(\d{4})(\d?)

替换:($1) $2-$3 ext $4

除了第 4 个捕获组是否存在,我都添加了“ext”,所以我得到了:

  1. 1112223333 > (111) 222-3333 ext(应该是(111) 222-3333(没有“ext”后缀)

  2. 11122233334 > (111) 222-3333 ext 4(正确)

我知道我可以通过代码/评估匹配来做到这一点(我正在使用 C#/.Net 编程),但我更想知道 是否有办法更改替换正则表达式本身 是否有某种形式的逻辑,仅当且仅当有第 4 个捕获组时才添加后缀 ext $4

【问题讨论】:

  • 你可以使用If-Then-Else Conditionals
  • @JohnBus​​tos 正则表达式引擎不会替换,它只会匹配。替换是语言/工具功能的一部分。
  • 在 .NET 中,您没有条件替换模式支持。在Regex.Replace 中使用回调。抱歉,这是正确的答案。
  • 检查是否可以安装 .NET 的 Boost 库。那么,你可以这样做。或 PCRE2(最新版本)。请注意,Notepad++ 可以做到这一点:) 试试(?<f>\d{3})(?<s>\d{3})(?<t>\d{4})(?<e>\d)? -> (?{e}\($+{f}\) $+{s}-$+{t} ext $+{e}:\($+{f}\) $+{s}-$+{t})
  • 或者只是do two replaces: string txt = Regex.Replace(Regex.Replace(phone, @"(^\d{10})(\d)", "$1 ext $2"), @"(\d{3})(\d{3})(\d{4})", "($1) $2-$3");

标签: c# .net regex


【解决方案1】:

嗯,我能做到的最接近的方法是使用带有 C# 6 字符串插值的匹配评估器重载。

使用 C# 6 字符串插值的示例:

var phone = "01234567894";
var txt = Regex.Replace(
    phone,
    @"^(\d{3})(\d{3})(\d{4})(\d?)$",
    m => $"({m.Groups[1]}) {m.Groups[2]}-{m.Groups[3]}{(m.Groups[4].Success ? " ext " + m.Groups[4].Value : "")}");

或者,如果使用较旧的 C#,则使用 String.Format

var phone = "01234567894";
var txt = Regex.Replace(
    phone,
    @"^(\d{3})(\d{3})(\d{4})(\d?)$",
    m => String.Format("({0}) {1}-{2}{3}", m.Groups[1], m.Groups[2], m.Groups[3],
        m.Groups[4].Success ? " ext " + m.Groups[4].Value : ""));

【讨论】:

  • 谢谢,米格尔。我在我的 C# 程序中做了一个非常相似的事情,我更希望看看是否有可能使用正则表达式引擎本身而不是通过代码,但是非常感谢您的时间和工作!
  • 不幸的是,文档没有提到您想要的任何内容:msdn.microsoft.com/en-us/library/ewy2t5e0(v=vs.110).aspx
  • 这就是现在使用默认 Regex 类的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-27
  • 2014-06-19
  • 2010-11-19
  • 1970-01-01
  • 1970-01-01
  • 2019-01-27
  • 1970-01-01
相关资源
最近更新 更多