正则表达式只能正确拉出第一次出现

时间:2014-05-04 06:25:42

标签: regex

我正在尝试使用regexp提取数据库表的列定义,但我似乎无法破解它:

这是我的表达:

(\".*?),\"

这是表数据的示例:

"tstamp" DATETIME NOT NULL  DEFAULT (datetime('now','localtime')) ,"macid" VARCHAR NOT NULL ,"id" INTEGER NOT NULL  DEFAULT (null) ,"info" VARCHAR,"temp" DOUBLE NOT NULL , "altemp" DOUBLE, "active" BOOL DEFAULT true, "emailts" INTEGER, "alarmts" INTEGER DEFAULT 0, "algrace" INTEGER DEFAULT 15, 'sid' VARCHAR, 'led' INTEGER DEFAULT 0, 'sends' INTEGER DEFAULT 0, PRIMARY KEY ("macid","id")

这就是我所追求的:

"tstamp" DATETIME NOT NULL  DEFAULT (datetime('now','localtime'))
"macid" VARCHAR NOT NULL
"id" INTEGER NOT NULL  DEFAULT (null)
...

但我得到的是:

"tstamp" DATETIME NOT NULL  DEFAULT (datetime('now','localtime'))
" VARCHAR NOT NULL
" INTEGER NOT NULL  DEFAULT (null)
...

它似乎忽略了开始标准,只有第一次点击是正确的。

我做错了什么?

在线正则表达式

http://regex101.com/r/aJ2uW5

1 个答案:

答案 0 :(得分:4)

在我看来,你想要这样的东西:

['"].*?(?=,\s*(?![^)(]*\))['"]|$)

Demo on regex101

我们匹配一个开头报价,然后懒洋洋地将所有内容与.*?匹配,直至我们的前瞻(?=,\s*(?![^)(]*\))['"]|$)能够断言以下字符 逗号后跟可选空格(后面没有任何数量的非parens字符后跟一个右括号)和一个结束引号, OR 字符串的结尾($锚点)

这是一口吗?

是的,确实如此。下面的可视化和逐个令牌演练为您提供了更多细节,但在我看来,在全功能的正则表达式工具中构建这样的表达式是无可替代的。通过这种方式,您可以在创建表达式时实时演变您的匹配。

原作有什么问题?

您的匹配实际上吃了以下逗号并打开引号:,\"因此,在第一次匹配后,引擎与字符串不同步。

令牌令牌解释

  • 匹配“'"”['"]
  • 列表中的单个字符
  • 匹配任何非换行符(换行符)的单个字符.*?
    • 在零和无限时间之间,尽可能少地根据需要进行扩展(懒惰)*?
  • 断言下面的正则表达式可以匹配,从这个位置开始(正向前瞻)(?=,\s*(?![^)(]*\))['"]|$)
    • 匹配此备选方案(仅在此方案失败时尝试下一个备选方案),\s*(?![^)(]*\))['"]
      • 匹配字符“,”字面意思,
      • 匹配单个字符“空格字符”(ASCII空格,制表符,换行符,回车符,垂直制表符,换页符)\s*
        • 在零和无限次之间,尽可能多次,根据需要回馈(贪婪)*
      • 断言从这个位置(负向前瞻)(?![^)(]*\))开始,无法匹配下面的正则表达式
        • 匹配列表中不存在的任何单个字符“){”[^)(]*
          • 在零和无限次之间,尽可能多次,根据需要回馈(贪婪)*
        • 匹配字符“)”字面意思\)
      • 匹配“'"”['"]
      • 列表中的单个字符
    • 或者匹配此替代方案(如果此组无法匹配则整个组都会失败)$
      • 断言字符串末尾的位置,或字符串末尾的换行符之前的位置(如果有的话)(换行符)$

Regular expression visualization

Debuggex Demo