【问题标题】:Regular expression for single pairs of (nested) brackets, BUT excluding inter-leaved ones?单对(嵌套)括号的正则表达式,但不包括交错括号?
【发布时间】:2021-07-30 15:37:18
【问题描述】:

在 SO 和其他地方有很多用于匹配括号或括号对的解决方案,但我找不到或想出排除交错项目的解决方案。这个挑战的解决方案是什么:

Write a regular expression for a string containing any number of X 
and single pairs of < > and { } which may be nested but not 
inter-leaved. For example these strings are allowed:

XXX<XX{X}XXX>X
X{X}X<X>X{X}X<X>X

But these are not allowed:

XXX<X<XX>>XX
XX<XX{XX>XX}XX

这完全可以用正则表达式(有限自动机)来完成吗?不需要下推自动机吗?

除了不交错之外,请注意对单对的要求,这意味着嵌套可能只有一层深度,不同的括号类型,如图所示。

没有偏好使用哪种正则表达式引擎/语言。

【问题讨论】:

  • @AKSingh OP 应该写一个正则表达式。使用堆栈不是正则表达式。
  • 我想到了like this

标签: regex parsing state-machine regular-language


【解决方案1】:

X 成为[^&lt;&gt;{}] 的简写。那么需要的正则表达式为:

(X|<(X|{X*})*>|{(X|<X*>)*})*

或者,完整地写出来,

([^<>{}]|<([^<>{}]|{[^<>{}]*})*>|{([^<>{}]|<[^<>{}]*>)*})*

https://regex101.com/r/f93EOs/1

【讨论】:

  • 简单而严谨!我很享受“让 X 成为……”的思考方式,因为它简化了任务并引导您找到正确的解决方案。谢谢!
【解决方案2】:

使用

^[^<>{}]*(?:(?:<[^<>]*>|{[^{}]*})+[^<>{}]*)*$

regex proof

解释

--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  [^<>{}]*                 any character except: '<', '>', '{', '}'
                           (0 or more times (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  (?:                      group, but do not capture (0 or more times
                           (matching the most amount possible)):
--------------------------------------------------------------------------------
    (?:                      group, but do not capture (1 or more
                             times (matching the most amount
                             possible)):
--------------------------------------------------------------------------------
      <                        '<'
--------------------------------------------------------------------------------
      [^<>]*                   any character except: '<', '>' (0 or
                               more times (matching the most amount
                               possible))
--------------------------------------------------------------------------------
      >                        '>'
--------------------------------------------------------------------------------
     |                        OR
--------------------------------------------------------------------------------
      {                        '{'
--------------------------------------------------------------------------------
      [^{}]*                   any character except: '{', '}' (0 or
                               more times (matching the most amount
                               possible))
--------------------------------------------------------------------------------
      }                        '}'
--------------------------------------------------------------------------------
    )+                       end of grouping
--------------------------------------------------------------------------------
    [^<>{}]*                 any character except: '<', '>', '{', '}'
                             (0 or more times (matching the most
                             amount possible))
--------------------------------------------------------------------------------
  )*                       end of grouping
--------------------------------------------------------------------------------
  $                        before an optional \n, and the end of the
                           string

【讨论】:

  • 我没想到解决方案会如此简单和优雅。我太专注于尝试排除交错的左括号,而解决方案是排除右括号。非常整洁,谢谢!
  • &lt;[^&lt;&gt;]*&gt; 当然拒绝嵌套尖括号。但它允许不匹配(或过度嵌套)的大括号。还是我错过了什么?
  • rici 是对的,正如他的证明所示。我很高兴忽略了允许的不匹配大括号,因为挑战没有解决问题,但我错过了正则表达式允许过度嵌套。我现在已经接受了 rici 的回答。这个答案在其他用例中会很有用,我仍然喜欢它!
猜你喜欢
  • 2020-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-27
  • 2014-10-09
相关资源
最近更新 更多