【问题标题】:What my Regexp should be?我的正则表达式应该是什么?
【发布时间】:2018-05-18 13:55:15
【问题描述】:

我正在尝试从字符串定义中获取所有检查约束,如下所示

  CREATE TABLE products(
     id INT PRIMARY KEY     NOT NULL,
     price         REAL,
     title         TEXT,
     CONSTRAINT price_check CHECK (  price > 0),
     constraint title_check CHECK (length(title) > 5 AND (price <= 100.0))
  );

使用以下正则表达式 /CONSTRAINT\s+(\w+)\s+CHECK\s+\((.+?)\)/i 但它不匹配第二个约束,只有 constraint title_check CHECK (length(title) 的一部分。

我应该如何更改我的正则表达式(如果可以的话)以使其正常工作?正则表达式的特定语言方言无关紧要。感谢您的帮助。

【问题讨论】:

  • 您是否尝试过使用其中一种在线正则表达式工具?
  • 删除使+变得懒惰的?
  • @SagarPandya:如果在 CHECK 括号内输入换行符,这将失败。如果你将表达式设为多行,那么正则表达式会吞食太多。

标签: javascript python ruby regex


【解决方案1】:

Ruby 的 Onigmo 引擎非常强大,并且允许您检查括号嵌套。

/CONSTRAINT\s+(\w+)\s+CHECK\s+(?<paren>\((?:[^()]|\g<paren>)+\))/i

末尾的位 (?&lt;paren&gt;\((?:[^()]|\g&lt;paren&gt;)+\)) 是平衡括号表达式的递归定义:“paren”是开括号,然后是非括号字符或“paren”,重复任意次数;然后是一个右括号;我们现在想要其中之一。

很遗憾,Python 和 JavaScript 都不允许您这样做。

【讨论】:

  • 哇,看起来有点复杂。我怎样才能捕获约束的名称(例如price_check)并从捕获的表达式中删除括号(来自这个(price &gt; 0))?
  • 为此,我们将递归稍微翻转一下:/CONSTRAINT\s+(?&lt;name&gt;\w+)\s+CHECK\s+\((?&lt;content&gt;(?&lt;token&gt;[^()]|\(\g&lt;content&gt;\))+)\)/i,然后检查namecontent 捕获。
  • @therhino:确实,如果您从我的评论中复制,由于某种原因,在两个地方(零宽度非连接符,零宽度空间)有额外的 \u200c\u200b,这会阻止正则表达式工作。不知道他们是怎么偷偷溜进去的。这是一个正确的(即使看起来完全一样):rubular.com/r/ziY9RWdCJ6
【解决方案2】:

console.log("CREATE TABLE products(\nid INT PRIMARYNULL,\npriceREAL,\ntitleTEXT,\nCONSTRAINT price_check CHECK (  price &gt; 0),\nconstraint title_check CHECK (length(title) &gt; 5 AND (price &lt;= 100.0))\n  );".match(/^.*constraint.*check.*$/gim));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-16
    • 1970-01-01
    • 2010-09-15
    • 2011-06-15
    • 2015-06-09
    相关资源
    最近更新 更多