我有一个查询,想获取 from & where
之间的表名
如果它是没有别名的单行单表,我可以这样做:
(?<=from )([^#]\w*)(?=.*where)
我需要获取除前缀表之外的每个表。即 course c
marks s
但我想不出以下查询的正则表达式。
(where
子句可以在同一行或新行中,在行首或带有空格或制表符)
from #prefix#student, course c, marks m
where ....
有些地方还有子查询,如果这种情况也能处理就好了。
select ... from course c
where id = (select ... from student where ...)
我正在尝试在 sublime text 3
编辑器中查找和替换
测试用例查询:
//output [course]
select ... from course
where ...
//output [course c] [marks s]
select ... from course c, marks s
where ....
//output [marks m]
select ... from #prefix#course c, marks m
where ...
//output [student s]
select ... from #prefix#course c
where id = (select ... from student s where ...)
最佳答案
您可以使用以下正则表达式:
\bfrom\b(?!\s*#)([^w]*(?:\bw(?!here\b)[^w]*)*)\bwhere\b
参见 regex demo
检查区分大小写选项以备不时之需。
如果您只需要突出显示 from
之间的所有内容和 where
, 使用环视:
(?<=\bfrom\b)(?!\s*#)([^w]*(?:\bw(?!here\b)[^w]*)*)(?=\bwhere\b)
参见 another demo以及显示结果的屏幕:
正则表达式分解:
-
(?<=\bfrom\b)
- 检查是否有一个完整的单词from
在下一个之前... -
(?!\s*#)
- 确保没有 0 个或多个空格后跟#
-
([^w]*(?:\bw(?!here\b)[^w]*)*)
- 匹配任何不是where
的文本直到... -
(?=\bwhere\b)
- 一个完整的词where
.
更新
由于您需要获取以逗号分隔的值(不包括带别名的前缀名称),因此您需要一个边界约束的正则表达式。可以用 \G
来实现运算符(operator):
(?:\bfrom\b(?:\s*#\w+(?:\s*\w+))*+|(?!^)\G),?\s*\K(?!(?:\w+ )?\bwhere\b)([\w ]+)(?=[^w]*(?:\bw(?!here\b)[^w]*)*\bwhere\b)
这里,
-
(?:\bfrom\b(?:\s*#\w+(?:\s*\w+))*+|(?!^)\G)
- 火柴from
(作为一个完整的单词)后跟可选的空格,后跟#
和 1 个或多个后跟空格 + 字母数字(别名)的字母数字 -
,?\s*\K
- 可选(1 或 0)逗号后跟 0 个或多个空格,后跟\K
这强制引擎忽略匹配得如此粗的整个文本 block -
(?!(?:\w+ )?\bwhere\b)
- 限制性前瞻,我们禁止下一个或下一个单词后面的单词等于where
-
([\w ]+)
- 我们的匹配项,1 个或多个字母数字或空格(可以替换为[\w\h]+
) -
(?=[^w]*(?:\bw(?!here\b)[^w]*)*\bwhere\b)
- 尾随边界:必须有除where
以外的文本到第一个where
.
关于正则表达式获取两个字符串中的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33690780/