Python 要匹配[^';]但也要匹配\';串

Python 要匹配[^';]但也要匹配\';串,python,sql,regex,parsing,Python,Sql,Regex,Parsing,我正在解析一个.SQL文件并尝试将其写入Mongodb 我用了这个正则表达式 \((\d+),'([^']+)'(?:,(\d+))(?:,(\d+))(?:,(\d+))\) ,它适用于大多数情况 (431532,'Fluorescent_cheese_dyes',0,0,0),(431533,'Christian_Rock_albums',0,0,0), (431534,'Variety_radio_stations',0,0,0),(431535,'Dean\'s_list',0,0,0

我正在解析一个.SQL文件并尝试将其写入Mongodb

我用了这个正则表达式

\((\d+),'([^']+)'(?:,(\d+))(?:,(\d+))(?:,(\d+))\)
,它适用于大多数情况

(431532,'Fluorescent_cheese_dyes',0,0,0),(431533,'Christian_Rock_albums',0,0,0),
(431534,'Variety_radio_stations',0,0,0),(431535,'Dean\'s_list',0,0,0),
但在最后一个例子中,关于哪里有
\'
,它没有这样做,因为我使用了
'([^']+)
来匹配字符串。当我将
'([^']+)'
更改为
'((?:(?:\)|[^']+)
时,它将匹配一个实例中的所有案例,而不是4个。分组如下:

1.  431532
2.  Fluorescent_cheese_dyes',0,0,0),(431533,'Christian_Rock_albums',0,0,0),(431534,'Variety_radio_stations',0,0,0),(431535,'Dean\'s_list
3.  0
4.  0
5.  0

如果第二组将字符串与
\'
匹配,我该如何处理呢?

我建议将
'([^']+)'
替换为
'([^']\\')+)

字符串被单引号包围。它包含以下一个或多个实例:

  • 除单引号外的字符,或
  • 单引号由一个反斜杠转义

只需使用非贪婪的
+?


示例:

看起来您必须解释引号中的任何转义

 # \((\d+),'((?:\\[\S\s]|[^'\\])*)'(?:,(\d+))(?:,(\d+))(?:,(\d+))\)

 \(
 ( \d+ )                             # (1)
 ,
 '
 (                                   # (2 start)
      (?: \\ [\S\s] | [^'\\] )*
 )                                   # (2 end)
 '
 (?:
      ,
      ( \d+ )                        # (3)
 )
 (?:
      ,
      ( \d+ )                        # (4)
 )
 (?:
      ,
      ( \d+ )                        # (5)
 )
 \)

你在分析什么?我避免使用正则表达式解析(如果可能…)我正在解析sql转储。我不确定格式是什么,但似乎用括号将其包装可以创建元组列表,您可以
求值
:-)谢谢!我后来的正则表达式中的错误是我使用了
\'
而不是
\'
,这与任何东西都不匹配。
'(([^']\\\')+)
匹配
'\'
@sln,是的,谁说不应该?如果反斜杠字符仅用于转义引号,并且输入字符串有效,则将有一个匹配的未转义单引号,贪婪的
+
将匹配到该单引号。这就是问题所在,它匹配
'\'
反斜杠字符仅用于转义引号时,没有结束引号。如果你说输入是有效的,这可能是一个没有实际意义的观点,但是为什么要尝试匹配一个所谓的平衡报价呢?通过使用这个标准,
(.*)@sin,你的观点是清楚的。另一方面,我的也是。要解析的内容的规范应该是明确的,不应该依赖于懒惰与否。我建议的正则表达式几乎是确定性的(您必须从否定类中排除反斜杠,使其完全确定性,这是我建议的,如果我完全知道Gi想要做什么,例如,
”(([^'\]\\\\'\\\\\\\\\\\\\\\\\\\\\\\\\+)
)。另一方面,懒惰的重复并没有那么明显,它会导致回溯和性能损失。如果你分别匹配这5个元组中的每一个,这就可以了。我相信如果一个字符串包含多个正则表达式,并尝试将其与
R*
匹配,您会遇到各种各样的问题,其中
R
是您的整个正则表达式。@nickie不符合regex101的要求-您可以在一行中添加任意多个全局修饰符,并将它们全部匹配。我认为这是一个更好的答案。
 # \((\d+),'((?:\\[\S\s]|[^'\\])*)'(?:,(\d+))(?:,(\d+))(?:,(\d+))\)

 \(
 ( \d+ )                             # (1)
 ,
 '
 (                                   # (2 start)
      (?: \\ [\S\s] | [^'\\] )*
 )                                   # (2 end)
 '
 (?:
      ,
      ( \d+ )                        # (3)
 )
 (?:
      ,
      ( \d+ )                        # (4)
 )
 (?:
      ,
      ( \d+ )                        # (5)
 )
 \)