正则表达式只能得到包含数字但不在方括号内的方括号

时间:2016-02-24 18:23:31

标签: c# .net regex

示例字符串

 "[] [ds*[000112]] [1448472995] sample string [1448472995] ***";

正则表达式应匹配

 [1448472995] [1448472995]

并且不应与[000112]匹配,因为有外方括号。

目前我的这个正则表达式匹配[000112]以及

const string unixTimeStampPattern = @"\[([0-9]+)]";

4 个答案:

答案 0 :(得分:4)

你需要使用balancing groups来处理这个问题 - 它看起来有点令人生畏,但并不是那么复杂:

Regex regexObj = new Regex(
    @"\[               # Match opening bracket.
    \d+                # Match a number.
    \]                 # Match closing bracket.
    (?=                # Assert that the following can be matched ahead:
     (?>               # The following group (made atomic to avoid backtracking):
      [^\[\]]+         # One or more characters except brackets
     |                 # or
      \[ (?<Depth>)    # an opening bracket (increase bracket counter)
     |                 # or
      \] (?<-Depth>)   # a closing bracket (decrease bracket counter, can't go below 0).
     )*                # Repeat ad libitum.
     (?(Depth)(?!))    # Assert that the bracket counter is now zero.
     [^\[\]]*          # Match any remaining non-bracket characters
     \z                # until the end of the string.
    )                  # End of lookahead.", 
    RegexOptions.IgnorePatternWhitespace);

答案 1 :(得分:4)

使用平衡文本这是一种很好的方法。

    ( \[ \d+ \] )                 # (1)
 |                             # or,
    \[                            # Opening bracket
    (?>                           # Then either match (possessively):
         [^\[\]]+                      #  non - brackets
      |                              # or
         \[                            #  [ increase the bracket counter
         (?<Depth> )
      |                              # or
         \]                            #  ] decrease the bracket counter
         (?<-Depth> )
    )*                            # Repeat as needed.
    (?(Depth)                     # Assert that the bracket counter is at zero
         (?!)
    )
    \]                            # Closing bracket

C#样本

string sTestSample = "[] [ds*[000112]] [1448472995] sample string [1448472995] ***";
Regex RxBracket = new Regex(@"(\[\d+\])|\[(?>[^\[\]]+|\[(?<Depth>)|\](?<-Depth>))*(?(Depth)(?!))\]");

Match bracketMatch = RxBracket.Match(sTestSample);
while (bracketMatch.Success)
{
    if (bracketMatch.Groups[1].Success)
        Console.WriteLine("{0}", bracketMatch);
    bracketMatch = bracketMatch.NextMatch();
}

输出

[1448472995]
[1448472995]

答案 2 :(得分:0)

您是否只想捕获unix时间戳?然后,您可以尝试更简单的一个,指定组中匹配的最小字符数。

\[([0-9]{10})\]

这里我将其限制为10个字符,因为我怀疑时间戳会很快达到11个字符...为了防止这种情况:

\[([0-9]{10,11})\]

当然,如果你在一个封闭的括号中有一个10长的数字,这可能会导致误报。

答案 3 :(得分:-2)

这将按预期匹配您的表达式:http://regexr.com/3csg3它使用前瞻。