把两个正则表达式连接起来不起作用

编程语言 2026-07-11

我在尝试用两个类似的正则表达式来实现匹配。

第一个:

(constraint\s+\w*)*primary key\s*((on\s+conflict\s+\w*)*\s*(autoincrement)*

第二个:

(constraint\s+\w*)*primary key\s*(autoincrement)*\s*(on\s+conflict\s+\w*)*

它们都能正常工作。

然而,当我尝试通过剪切并粘贴将它们连接在一起时:

(constraint\s+\w\*)\*primary key\s\*(((on\s+conflict\s+\w\*)\*\s\*(autoincrement)\*)|((autoincrement)\*\s\*(on\s+conflict\s+\w\*)\*))

它不再起作用。

我在regex101上用以下5 个字符串进行测试:

字符串1(用于下文的情况2):

CREATE TABLE leagues_new(id INTEGER PRIMARY KEY AUTOINCREMENT ON CONFLICT ABORT, name TEXT, drafttype INTEGER, scoringtype INTEGER, roundvalues INTEGER, leaguetype TEXT,  salary INTEGER, benchplayers INTEGER);

字符串2(用于下文的情况1):

CREATE TABLE leagues_new(id INTEGER PRIMARY KEY ON CONFLICT ABORT AUTOINCREMENT, name TEXT, drafttype INTEGER, scoringtype INTEGER, roundvalues INTEGER, leaguetype TEXT,  salary INTEGER, benchplayers INTEGER);

字符串3(用于下文的情况3):

CREATE TABLE leagues_new(id INTEGER PRIMARY KEY ON CONFLICT ABORT, name TEXT, drafttype INTEGER, scoringtype INTEGER, roundvalues INTEGER, leaguetype TEXT,  salary INTEGER, benchplayers INTEGER);

字符串4(用于下文的情况4):

CREATE TABLE leagues_new(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, drafttype INTEGER, scoringtype INTEGER, roundvalues INTEGER, leaguetype TEXT,  salary INTEGER, benchplayers INTEGER);

字符串5(用于下文的情况5);

CREATE TABLE leagues_new(id INTEGER PRIMARY KEY, name TEXT, drafttype INTEGER, scoringtype INTEGER, roundvalues INTEGER, leaguetype TEXT,  salary INTEGER, benchplayers INTEGER);

我只是想匹配 (a b) || (b a) 的模式。

请注意,我并不是要解析SQL。我只是想从SQLite中提取信息,因为它并不支持所有“大型关系数据库管理系统”的特性。

我用C++编写,但为了让生活更轻松,我把在regex101上尝试的正则表达式粘贴过来,以便更容易理解。

使用以下:

(constraint\s+\w+)*primary key\s*(\b((autoincrement)*\s*(on\s+conflict\s+\w+)*)\b|(\b(on\s+conflict\s+\w+)*\s*(autoincrement)*)\b)

对照:

CREATE TABLE leagues_new(id INTEGER PRIMARY KEY ON CONFLICT ABORT AUTOINCREMENT, name TEXT, drafttype INTEGER, scoringtype INTEGER, roundvalues INTEGER, leaguetype TEXT,  salary INTEGER, benchplayers INTEGER)

根据regex101的结果,匹配 "PRIMARY KEY ON CONFLICT ABORT" ,这是部分匹配。如何让它在这5 种情况下一致地工作:

  1. 第一个出现ON CONFLICT ABORT,第二个出现AUTOINCREMENT
  2. 第一个出现AUTOINCREMENT,第二个出现ON CONFLICT ABORT
  3. 第一个出现ON CONFLICT ABORT,AUTOICREMENT未出现
  4. 第一个出现AUTOINCREMENT,ON CONFLICT ABORT未出现
  5. 第一个未出现ON CONFLICT ABORT,AUTOINCREMENT未出现。

使用以下正则表达式:

(constraint\s+\w+)*primary key\s*(((autoincrement)\s*\b(on\s+conflict\s+\w+)\b)|(\b(on\s+conflict\s+\w+)\b\s*(autoincrement)))?

我可以匹配情况1 和情况2,但情况3 和4 失败。

解决方案

如果对正则表达式做一点小修正,在主要捕获之间允许随机文本,并添加一个简单的 .*?,你的正则就应该能匹配所有情况。

(constraint\s+\w+\s+)*primary\s+key\s+(((on\s+conflict\s+\w+).*?\s+(autoincrement))|((autoincrement).*?\s+(on\s+conflict\s+\w+)))

https://regex101.com/r/7R0yAa/1

为便于理解,格式化如下

( constraint \s+ \w+ \s+ )*               # (1)
primary \s+ key \s+ 
(                                         # (2 start)
   (                                         # (3 start)
      ( on \s+ conflict \s+ \w+ )               # (4)
      .*? \s+ 
      ( autoincrement )                         # (5)
   )                                         # (3 end)
 | 
   (                                         # (6 start)
      ( autoincrement )                         # (7)
      .*? \s+ 
      ( on \s+ conflict \s+ \w+ )               # (8)
   )                                         # (6 end)
)                                         # (2 end)
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章