【问题标题】:Get list of parameter names from native sql expression (regex)从本机 sql 表达式(正则表达式)获取参数名称列表
【发布时间】:2022-09-27 16:04:17
【问题描述】:

我在使用 Regex 获取 SQL 查询中的所有参数列表时遇到问题。

查询示例:

SELECT ... WHERE col1 = :user AND col2 = \'HELLO\' OR col3 = :language

要获取参数,我使用以下正则表达式模式:

Pattern.compile(\":([\\\\w.$]+|\\\"[^\\\"]+\\\"|\'[^\']+\')\", Pattern.MULTILINE)

该模式正确返回参数列表:

:user
:language

问题在于另一种类型的查询,其中文字可能包含字符 \':\'

WHERE col1 = :user AND some_date > \'2022-09-26T10:22:55\'

这种情况下的参数列表是:

:user
:22
:55

有没有更好的方法不将文字内容视为参数?

  • Pattern.compile(\"[^\'\\\":]*:([\\\\w.$]+|\\\"[^\\\"]+\\\"|\'[^\']+\')\", Pattern.MULTILINE)
  • 感谢您的回复。但在场景中:code <> \'*\'\\nAND code IN (select x from ... where user = :user) 它认为\\nAND code IN (select x from ... where user = :user 是参数。
  • Pattern.DOT_ALL 将让 . 也匹配换行符。忘记了

标签: java sql regex


【解决方案1】:

您可以通过假设 sql 中的命名参数只是一个带有前缀 : 的单词并且总是跟在一个空格之后来简化您的问题(这实际上不是要求或始终正确,但可能足以让您获得可接受的结果尽可能简单的正则表达式)

Pattern.compile(" :\\w+", Pattern.MULTILINE)

--

cmets总结:

had to match 
- foo = :param AND :param = bar AND foo=:param AND :param=bar
- AND FUNC(:param) OR FUNC(0, :param) OR FUNC(:param, 0)

最后,这个具有固定长度前瞻和可变长度后瞻的正则表达式很有帮助:

 Pattern.compile("(?<=[=(])\\s*:[\\w_.]+|:[\\w_.]+(?=\s*[=)])", Pattern.MULTILINE)

【讨论】:

  • 感谢你的回答。尽我所能,我不能。在我的查询中,有包含“_”或“。”的参数。也可能不以空格为前缀。不幸的是,我无法影响它,因为 sql 查询是以某种方式外部生成的。
  • Pattern.compile("(?&lt;==) ?:[\\w_.]+, Pattern.MULTILINE) 使用正则表达式lookbehind 并假设在= 之后遵循参数是什么?
  • 那么参数并不总是在 = 运算符之后。你可以有:parameter = 'ABC'(倒置)的场景。
  • 所以它是向后看或向前看。 (lookbehind 必须是固定长度...不能包含带有空格的变量)(?&lt;==)\s*:[\w_.]+|:[\w_.]+(?=\s*=)rubular.com/r/BmGCgJdZ4bZFkR
  • 这个效果更好,但我仍然面临函数调用AND FUNC(:param) OR FUNC(0, :param) OR FUNC(:param, 0) 的问题编辑:我使用的正则表达式一直在正确匹配所有内容,但不知何故你的确实正确地忽略了文字。 rubular.com/r/uZ9BsgOqpU0KkH
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-11
  • 2019-08-09
  • 2013-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多