首页 > 解决方案 > 如何使用正则表达式突出显示 SQL 关键字?

问题描述

我想在语法荧光笔中突出显示字符串中出现的 SQL 关键字。以下是我想要的规则:

这当然并不全面(可以忽略字符串中的转义),但我想从这里开始。

这里有一些例子:

SELECT * FROM main""" -- 不,字符串不以关键字开头 (SELECT...)。

我认为在单个正则表达式中执行此操作的唯一方法是向后看负数……但它不会是固定宽度,因为我们不知道字符串何时开始。就像是:

但这当然行不通:

在此处输入图像描述

这样的事情可以在单个正则表达式中完成吗?

标签: regexparsingkeyword

解决方案


一个合适的正则表达式可能会变得相当复杂,尤其是随着规则的进一步发展。正如其他人所指出的,可能值得考虑使用解析器。也就是说,这是一个可能的正则表达式,试图涵盖到目前为止提到的规则:

(["'])\s*(SELECT)(?:\s+.*)?\s+(FROM)(?:\s+.*)?\1(?:[^\w]|$)

正则表达式可视化

在线演示

  1. 调试演示
  2. 正则表达式 101 演示

解释

从上面的可视化中可以看出,正则表达式在开头查找双引号或单引号(保存在捕获组 #1 中),然后在末尾通过\1. 和关键字在捕获组#2 和#3 中捕获SELECT语法确保没有更多组用于其他选择,因为在选择开始时将其排除为捕获组。)还有一些进一步的可选细节,例如限制 and 之间允许的内容以及不计算最后的引号如果它紧跟一个单词字符。FROM(?:x|y)?:SELECTFROM

结果

SELECT * FROM tbl        -- no match - not in a string
"SELECT * FROM tbl"      -- matches - in a double-quoted string
'SELECT * FROM tbl;'     -- matches - in a single-quoted string
'SELECT * FROM it's      -- no match - letter after end quote
"SELECT * FROM tbl'      -- no match - quotation marks don't match
'SELECT * FROM tbl"      -- no match - quotation marks don't match
"select * from tbl"      -- no match - keywords not upper case
'Select * From tbl'      -- no match - still not all upper case
"SELECT col1 FROM"       -- matches - even though no table name
'  SELECT  col1  FROM '  -- matches - as above with more whitespace
'SELECT col1, col2 FROM' -- matches - with multiple columns

可能的改进?

可能还需要从“任何字符”部分中排除引号。这可以使用此处描述的技术通过替换 with 的两个实例以.*增加复杂性为代价来完成(?:(?!\1).)*

(["'])\s*(SELECT)(?:\s+(?:(?!\1).)*)?\s+(FROM)(?:\s+(?:(?!\1).)*)?\1(?:[^\w]|$)

请参阅此 Regex101 演示


推荐阅读