【问题标题】:Regular expression to match [^'] but also \' in string正则表达式匹配 [^'] 但也匹配字符串中的 \'
【发布时间】:2015-06-26 19:33:00
【问题描述】:

我正在解析一个 .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

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

【问题讨论】:

  • 你在解析什么?我避免使用正则表达式进行解析(如果可能...)
  • 我正在解析一个 sql 转储。
  • 我不确定格式是什么,但似乎用括号括起来可以创建一个元组列表,你可以eval :-)

标签: python sql regex parsing


【解决方案1】:

只需使用非贪婪的. (.+?)

\((\d+),'(.+?)'(?:,(\d+))(?:,(\d+))(?:,(\d+))\)

示例:https://regex101.com/r/zV0lZ1/1

【讨论】:

  • 如果您分别匹配这 5 个元组中的每一个,就可以了。我相信如果您有一个包含多个字符串的字符串并尝试将其与R* 匹配,那么您会遇到各种问题,其中R 是您的整个正则表达式。
  • @nickie 不符合 regex101 - 您可以使用全局修饰符在一行中添加尽可能多的内容,并且它们都匹配。
  • 我认为这是一个更好的答案。
【解决方案2】:

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

字符串用单引号括起来。它包含一个或多个实例:

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

【讨论】:

  • 谢谢!我后来的正则表达式中的错误是我使用了\' 而不是\\',它没有正确匹配任何东西。
  • '(([^']|\\')+)' 匹配 ' \'
  • @sln,没错,谁说不应该?如果反斜杠字符仅用于转义引号且输入字符串有效,则会有一个匹配的未转义单引号,并且贪婪的+会匹配到那个。
  • 就是这样,当backslash character is only used for escaping quotes匹配' \'时,没有结束引号。如果您说输入是有效的,这可能是一个有争议的问题,但是为什么要尝试匹配所谓的平衡报价呢?通过使用该标准,'(.*?)'<pseudo-anchors-here 实际上更有效。出于可转义分隔符的目的,很难想象转义本身不是可转义的。通常,闭包本身应该与周围的任何文字(其中 this 有很多)一样有效。
  • @sin,你的意见很明确。另一方面,我的也是。要解析的内容的规范应该是明确的,并且不应该依赖于懒惰与否。我建议的正则表达式几乎是确定性的(你必须从否定类中排除反斜杠,以使其完全确定,如果我完全知道 Gi 想要做什么,我会建议这样做,例如,'(([^'\\]|\\'|\\\\)+)') .另一方面,懒惰的重复并不那么清楚,它会导致回溯和性能损失。
【解决方案3】:

看起来您必须考虑引号中的任何转义。

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

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

【讨论】:

    猜你喜欢
    • 2011-11-08
    • 2019-09-13
    • 2023-03-13
    • 2012-06-05
    • 2013-12-25
    • 1970-01-01
    相关资源
    最近更新 更多