条件格式化数字字符串的正则表达式

时间:2013-03-06 14:41:21

标签: c# regex string

移除了原始问题


我正在寻找一个正则表达式,它将包含特殊字符,字符和数字的字符串格式化为仅包含数字的字符串。 在某些特殊情况下,仅使用“”(空)替换所有非数字字符是不够的。

1。)括号中的零。

  • 如果括号(0)中只有零,如果它是第一个括号对,则应将其删除。 (不应删除仅包含零的第二个括号对)

2。)领先零。

  • 应删除所有前导零(忽略括号)

更好理解的例子:

  • 123 (0) 123 would be 123123 (zero removed)
  • (0) 123 -123 would be 123123(zero and all other non-numeric characters removed)
  • 2(0) 123 (0) would be 21230 (first zero in brackets removed)
  • 20(0)123023(0) would be 201230230 (first zero in brackets removed)
  • 00(0)1 would be 1(leading zeros removed)
  • 001(1)(0) would be 110 (leading zeros removed)
  • 0(0)02(0) would be 20 (leading zeros removed)
  • 123(1)3 would be 12313 (characters removed)

4 个答案:

答案 0 :(得分:5)

您可以使用lookbehind 匹配(0),只有当不是在字符串的开头并用空字符串替换为你正在做。

(删除原始解决方案)


再次更新 以反映新要求

匹配前导零,匹配(0)仅当它是第一个带括号的项目,并匹配任何非数字字符时:

^[0\D]+|(?<=^[^(]*)\(0\)|\D

请注意,大多数正则表达式引擎都不支持可变长度的lookbehinds(即使用像*这样的量词),所以这只适用于几个正则表达式引擎 - .NET就是其中之一。 / p>

^[0\D]+      # zeroes and non-digits at start of string
|            # or
(?<=^[^(]*)  # preceded by start of string and only non-"(" chars
\(0\)        # "(0)"
|            # or
\D           # non-digit, equivalent to "[^\d]"

regexhero.net测试


您现在已经多次更改并添加了要求。对于像这样的多个规则,你可能最好单独为它们编码。如果一个条件匹配并且导致另一个条件不匹配则可能变得复杂且难以调试。例如,在单独的步骤中:

  1. 根据需要删除带括号的项目。
  2. 删除非数字字符。
  3. 删除前导零。
  4. 但是如果你绝对需要这三个条件都在一个正则表达式中匹配(不推荐),那么它就是。

答案 1 :(得分:1)

这个正则表达式应该非常接近你正在寻找的那个。

(^[^\d])|([^\d](0[^\d])?)+

(您可以替换空字符串捕获的所有内容)

编辑:

您的请求已经发展,现在变得复杂,只需一次通过即可。假设您始终在括号组之前获得了空格,您可以使用这些传递(保持此顺序):

string[] entries = new string[7] {
    "800 (0) 123 - 1",
    "800 (1) 123",
    "(0)321 123",
    "1 (0) 1",
    "1 (12) (0) 1",
    "1 (0) (0) 1",
    "(9)156 (1) (0)"
};
foreach (string entry in entries)
{
    var output = Regex.Replace(entry , @"\(0\)\s*\(0\)", "0");
    output = Regex.Replace(output, @"\s\(0\)", "");
    output = Regex.Replace(output, @"[^\d]", "");
    System.Console.WriteLine("---");
    System.Console.WriteLine(entry);
    System.Console.WriteLine(output);
}

答案 2 :(得分:1)

如果你可以使用多次传球,那么正则表达式会变得更加简单。我认为如果它不是字符串中的第一个东西,你可以做第一遍放弃你的(0),然后通过剥去非数字来跟随它:

var noMidStrParenZero = Regex.Replace(text, "^([^(]+)\(0\)", "$1");
var finalStr = Regex.Replace(noMidStrParenZero, "[^0-9]", "");

避免了很多正则表达式的疯狂,它也在一定程度上自我记录。

编辑:此版本也适用于您的新示例。

答案 3 :(得分:0)

(?:     # start grouping
    ^   # start of string
    |   # OR
    ^\( # start of string followed by paren
    |   # OR
    \d  # a digit
)       # end grouping
(0+)    # capture any number of zeros
|       # OR
([1-9]) # capture any non-zero digit

This works for all of your example strings,但整个表达式与(后跟零相匹配。您可以使用Regex.Matches使用全局匹配来获取匹配集合,然后将所有匹配的组连接到一个字符串中以仅获取数字(或者只删除任何非数字)。