SQL查找和替换正则表达式捕获组限制?

Posted

技术标签:

【中文标题】SQL查找和替换正则表达式捕获组限制?【英文标题】:SQL find-and-replace regular-expression capturing-group limit? 【发布时间】:2012-04-13 09:33:31 【问题描述】:

我需要将电子表格中的数据转换为 SQL 中的插入语句。我已经计算出了在 SSMS 中使用查找和替换工具的大部分正则表达式,但是当我尝试在最终替换中引用第 9 个带括号的项目时遇到了问题。

这是原始记录:

Blue Doe 12/21/1967 1126 Queens Highway Torrance CA 90802 N 1/1/2012

这就是我需要的(目前):

select 'Blue','Doe','19671221','1126 Queens Highway','Torrance','CA','90802','N','20120101'

由于允许的括号中的项目数量的限制,我必须运行 3 次替换。如果我可以先使它作为 POC 工作,这可能会在存储过程中起作用。

这是第一个匹配的表达式:

^:w:b:w:b:z/:z/:z:b[0-9A-Za-z:b]+:b:w:b[A-Z]+:b:z:b:w:b:z/:z/:z

然后替换:\10\2/0\3/\40\5/0\6/\7

这会将零添加到月份和日期,以便它们至少有两个字符。

下一个匹配将日期重新格式化为查询所需的格式(没有关于不使用日期字段的问题。这是数据库的客户要求)。

匹配表达式:

^:w:b:w:b[0-9]*[0-9]^2/[0-9]*[0-9]^2/:z:b[0-9A-Za-z:b]+:b:w:b[A-Z]+:b:z:b:w:b[0-9]*[0-9]^2/[0-9]*[0-9]^2/:z

然后替换:\1\4\(2,2)\(2,3)\5\8\(2,6)\(2,7)

最后,最终匹配将结果插入到将在插入语句中使用的 SQL 语句中。

匹配表达式:

^:w:b:w:b:z:b[0-9A-Za-z:b]+:b:w:b[A-Z]+:b:z:b:w:b:z

然后替换:select '\1','\2','\3','\4','\5','\6','\7','\8','\9'

除了最后一次替换外,一切正常。由于某种原因, \9 没有从比赛中获取数据。如果我只是用 \9 替换整个替换表达式,我会得到一个空格。如果我使用 \8,我得到 N。如果我消除第 8 个括号中的项目,从而使我的第 9 个项目成为第 8 个,它会返回我想要的,20120101。

所以我的问题是,在使用查找/替换和正则表达式时,SSMS/SQL 是否允许 9 个标记表达式?或者我在这里错过了什么?我知道还有其他方法可以做到这一点。在我们将其移入存储过程或应用程序之前,我只是想以 POC 的形式快速完成它。

感谢您的帮助。 -彼得

【问题讨论】:

您可以直接从电子表格导入。数据是否已经在单独的列中? 为什么需要使用replace?如果数据来自电子表格并且您使用的是 SSMS,为什么不使用导入/导出管理器?另外,为什么要重新格式化数据,电子表格不支持 mm/dd/yyyy 日期格式?你不能写一些单元格公式来连接一个为你插入数据的字符串吗? 请编辑您的问题以添加正确的代码表达式格式。您可以通过以下方式执行此操作:用反引号包围 (""), selecting all and clicking the toolbar button `,或标记代码块并按 Ctrl+K。您可以在“提交问题”按钮正下方预览您的帖子(在发布之前)你正在输入它;预览会实时更新,所以它是一个所见即所得的视图。正确的格式可以让你的问题更容易阅读和理解,因此你更有可能得到答案。谢谢。:) 谢谢大家,但这些是我必须克服的限制。数据以我所说的格式出现。在插入语句中添加的其他数据不是来自此工作表,因此直接导入将不起作用。我不是在寻找替代解决方法。我需要完成这项工作。谢谢 @Peter Anderson 不要忘记接受答案并告诉我们您的决定。此外,如果您知道为什么查找/替换表达式不起作用,那将是很好的。 【参考方案1】:

您的匹配表达式均不适用于您在我的 MS SQL Server Management Studio 2008r2 中提供的记录。

根据您的描述,标记表达式 9 似乎存在问题,因为使用标记表达式 8 时返回了所需的结果,而不是 9。您可能想要ask Microsoft or report it as a bug。

更快的解决方案是将您在 SSMS 中执行查找/替换的文本移动到电子表格中,并使用单元格公式将数据解析为插入命令。如果您有 MS Excel,CONCATENATE、FIND 和 MID 函数可能会很有用。此外,它有助于将值拆分到它们自己的列中,这样您就可以格式化日期,然后使用一个连接来构建您的插入。

如果您需要示例,请告诉我。

更新:我在 MS SQL Server Management Studio 2008r2、Visual Studio 2005 和 Visual Studio 2010 中尝试了您的示例,得到的结果相同,\9 返回一个空字符串。环顾四周,我发现 others are also having this issue(参见 Henrique Evaristo 的社区内容),整个系统一直是 replaced in the new editors。

因此,在回答您的问题时,SSMS 不支持 9 个标记表达式,因为存在错误。

如果您无法使用电子表格的想法,您可以尝试将操作分成两部分,设置前 8 个值,然后再转回执行最后一个。例如:

^:w:b:w:b:z:b[0-9A-Za-z:b]+:b:w:b[A-Z]+:b:z:b:w:b:z
select '\1','\2','\3','\4','\5','\6','\7','\8','\0'

:w:b:w:b:z:b[0-9A-Za-z:b]+:b:w:b[A-Z]+:b:z:b:w:b:z
\1

【讨论】:

感谢您的回复。我认为它们不适合您的原因是它们粘贴到 SO 中的方式存在问题。我更新了原始文本以反映从 SQL 粘贴到 SO 时遇到的多个项目之间的“奇异空间”。 @Peter Anderson 更新了结果。我会切换到 excel 或编写自己的解决方案,但我提供了一个以防万一。您可能希望在 '\0' 前加上一个特殊字符,因为您将无法再按行搜索。或者,您可以更改第二个查询以在选择中找到“\0”并从那里开始工作。 感谢您对此的回答。这就是我需要的。最后感谢您提供的附加选项。我已经将这个东西拆分了三次以处理各种替换,我没有想到只使用 \0 并在第四次替换时使用最后一位。再次感谢。

以上是关于SQL查找和替换正则表达式捕获组限制?的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式 [REGEX] - 替换/替换 - 捕获组 1 和 2 中的内容

在 Javascript 中用大写替换正则表达式捕获组

具有捕获组的有效正则表达式,但 sed 脚本不起作用

如何仅对一个命名捕获组执行正则表达式替换?

C# - 正则表达式匹配模式、替换和捕获行号 [来自 Txt 文件]

Java正则表达式