c#条件正则表达式替换和电话格式

本文关键字:电话 格式 替换 条件 正则表达式 | 更新日期: 2023-09-27 18:15:22

是否有任何方法可以有条件地进行Regex替换?下面是一个例子。

假设你有一个号码,你知道它对应一个电话,没有格式:

5553331234

格式化后,它将是

(555)333-1234

但是,我们没有对数字进行格式化,并且想要应用格式化。您可以执行一个简单的正则表达式匹配,并使用以下内容捕获3组中的每组:

('d{3})('d{3})('d{4})
从那里,你可以做一个简单的正则表达式替换
($2)$3-$4
但是,如果可能有扩展名怎么办?也许你有超过10个标准的电话号码:
555333123456789

其中56789是分机。在这种情况下,我可以用

匹配它
('d{3})('d{3})('d{4})('d*)

如果我想格式化它,但只包含扩展名的X,如果存在,我可以这样做吗?例如,我可以让我的替换格式:

($2)$3-$4x$5

然而,如果我这样做,即使没有扩展,x也会显示出来。是否有一种方法纯粹使用正则表达式,使x有条件地显示?本质上应该是"if $5"存在或者"if $5. length()> 0"。

作为解决方法,我可以在正则表达式匹配中包含一个命名组,其中上面的('d*)变成

(?<Conditional>'d*)
在代码中,我可以断言名为"Conditional"的组的长度。然而,我想有一个纯粹的正则表达式的解决方案,不需要任何自定义像那样。

c#条件正则表达式替换和电话格式

看一下正则表达式中的替换-没有替换模式允许您编写条件。其他库,如boost::regex,确实提供了这样的功能,但在。net中没有。

所做的得到的是使用回调来提供替换的能力。只需使用lambda:

Regex.Replace(
    "555333123456789",
    @"('d{3})('d{3})('d{4})('d+)?",
    m => $"({m.Groups[1].Value}){m.Groups[2].Value}-{m.Groups[3].Value}{(m.Groups[4].Success ? $"x{m.Groups[4].Value}" : "")}"
)

是的,我知道这不是一个纯正则表达式解决方案,但它完成了它的工作。请记住,替换不是真正的一个正则表达式操作,它是一个匹配后的步骤,它涉及到匹配的结果,但是涉及到正则表达式引擎本身。

您可以使用Regex.Replace的过载,它接受MatchEvaluator,这将允许您根据匹配的组执行条件逻辑。

var phone = "5553331234";
Regex phoneRegex = new Regex(@"('d{3})('d{3})('d{4})('d*)");
var formatted = phoneRegex.Replace(
    phone, 
    m => string.Format(
        "({0}){1}-{2}{3}{4}", 
        m.Groups[1].Value, 
        m.Groups[2].Value, 
        m.Groups[3].Value, 
        m.Groups[4].Value.Length > 0 ? "x" : string.Empty, 
        m.Groups[4].Value));
Console.WriteLine(formatted);