正则表达式 - 如果捕获组存在,则条件替换

13
假设我有以下两个表示电话号码的字符串:
  1. 1112223333
  2. 11122233334
第一个是普通电话号码 (111) 222-3333,第二个是带分机号码的电话号码 (111) 222-3333 ext 4 所以我们知道电话号码始终是10位数字,可能是11位。如果是11位,则我想用第二种格式进行格式化。
我的当前正则表达式和替换如下: Regex: (\d{3})(\d{3})(\d{4})(\d?) Replacement: ($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

4
您可以使用If-Then-Else条件语句 - Maroun
4
@JohnBustos的正则表达式引擎只做匹配而不是替换。替换是语言/工具功能的一部分。 - Maroun
4
在.NET中,你没有条件替换模式的支持。在Regex.Replace内部使用回调函数。抱歉,但这是正确的答案。 - Wiktor Stribiżew
1
检查是否可以为.NET安装Boost库。然后,您可以这样做。或者PCRE2(最新版本)。请注意,Notepad ++可以做到这一点 :) 尝试(?<f>\d{3})(?<s>\d{3})(?<t>\d{4})(?<e>\d)?-> (?{e}\($+{f}\) $+{s}-$+{t} ext $+{e}:\($+{f}\) $+{s}-$+{t}) - Wiktor Stribiżew
2
或者只需进行两次替换string txt = Regex.Replace(Regex.Replace(phone, @"(^\d{10})(\d)", "$1 ext $2"), @"(\d{3})(\d{3})(\d{4})", "($1) $2-$3"); - bobble bubble
显示剩余8条评论
1个回答

4

嗯,我能找到的最接近的方法是使用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 : ""));

谢谢,Miguel。我在我的C#程序中做了类似的事情,我更希望看到是否有可能直接使用正则表达式引擎而不是通过代码来实现,但非常感谢您花费时间和精力! - John Bustos
1
不幸的是,文档中没有提到你想要的内容:https://msdn.microsoft.com/zh-cn/library/ewy2t5e0(v=vs.110).aspx - Miguel Angelo
2
现在使用默认的Regex类就可以这样完成。 - Wiktor Stribiżew

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