【问题标题】:REGEX good start but need some excludingREGEX 良好的开端,但需要一些排除
【发布时间】:2017-11-27 23:03:43
【问题描述】:

我有那个正则表达式

\{([^{}]|(?R))*\}

与最外层括号内容匹配的很好

foo{
    subfoo{
       "foofoofoo..."
    }
}foo

//Matches :
//   {
//   subfoo{
//      "foofoofoo..."
//   } 
//}

但我需要添加一些排除:

  • 绕过位于单引号或双引号中的每个括号
  • 如果右括号后跟\s*,则不匹配; (分号之间有空格)

所以下面的文字应该给出:

foo{
   subfoo{
      "foofoofoo... { "
   }
}foo

//Matches :
//   {
//   subfoo{
//      "foofoofoo... { "
//   } 
//}

foo{foofoofoo} ;

//Matches nothing

谁能帮忙?

【问题讨论】:

  • #2 可以通过否定断言... \}(?!\s+) 轻松实现;同时#1我不确定是否可以使用正则表达式(特别是如果我们想忽略转义引号并在双引号字符串中说单引号)

标签: regex


【解决方案1】:

首先,将您的模式更改为展开版本(更高效):

\{[^{}]*+(?:(?R)[^{}]*)*+\}

然后,按照同样的想法,您可以轻松地将部分描述为引号:

\{[^{}"]*+(?:"[^"]*"[^{}"]*|(?R)[^{}"]*)*+\}

(同样也包括单引号,从否定字符类中排除单引号并添加一个描述引用部分的分支)

您也可以考虑转义引号:

\{[^{}"]*+(?:"[^"\\]*+(?s:\\.[^"\\]*)*+"[^{}"]*|(?R)[^{}"]*)*+\}

如果您不希望结束大括号后跟;,请按照建议添加负前瞻。 (?!\s+;)(?!\s*;) 取决于你想要什么。但是,如果您只想定位最外面的右括号,则必须使用条件语句(?(condition)then|else)(?(R)|(?!\s+;))(?(R)|(?!\s*;)) 来检查您是否处于递归中。

【讨论】:

  • 我几乎不知道 REGEXP 的基础知识。我在regex101.com 上尝试了您的示例,但它们返回了错误“(不完整的组结构”
  • @LePioo:这是一个错字,这取决于您想要什么:\{([^{}]*+(?:(?R)[^{}]*)*+)\} 可以在括号内进行捕获,或者如果您不需要它,则可以编辑版本。其他模式也一样。
  • 非常感谢! (我在这里重新发布了演示链接上的 REGEXP)\{[^{}"']*+(?:"[^"\]*+(?s:\\.[^"\]*)*+" [^{}"']*|'[^'\]*+(?s:\\.[^'\]*)*+'[^{}"']|(?R)[^{} "]*)*+\}(?(R)|(?!\s*;))
  • 还有一个问题:你知道这个 REGEX 是否可以在 javascript、python 甚至 C# 上解释吗?
  • @LePioo:Python,只有regex module。 Javascript,也许使用XRegExp.matchRecursive() 可以实现,但没有条件特性。 .net 语言,可能,但您必须重写模式以使用 平衡组 而不是递归。
猜你喜欢
  • 1970-01-01
  • 2014-12-10
  • 1970-01-01
  • 2015-03-09
  • 2012-10-10
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多