正则表达式获取两个字符串中的字符串

regex get string within two string

我有一个查询,想在 from & where 之间获取 table 个名字 如果它是单行和单行 table 没有别名我可以这样做:

(?<=from )([^#]\w*)(?=.*where)

除了前缀 table 之外,我需要获取每个 table。即 course c marks s

但我想不出以下查询的正则表达式。 where 子句可以在同一行或新行中,在行首或带有 space 或制表符)

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

选中区分大小写选项以备不时之需。

如果您只需要突出显示 fromwhere 之间的所有内容,请使用环视:

(?<=\bfrom\b)(?!\s*#)([^w]*(?:\bw(?!here\b)[^w]*)*)(?=\bwhere\b)

查看 another demo 和结果屏幕:

正则表达式细分:

  • (?<=\bfrom\b) - 检查下一个单词之前是否有一个完整的单词from...
  • (?!\s*#) - 确保没有 0 个或多个白色 space 后跟 #
  • ([^w]*(?:\bw(?!here\b)[^w]*)*) - 匹配任何不是 where 直到...
  • 的文本
  • (?=\bwhere\b) - 一个完整的单词 where.

更新

由于您需要获取逗号分隔值(不包括带别名的前缀名称),因此您需要一个边界约束的正则表达式。它可以通过 \G 运算符来实现:

(?:\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(整个单词)后跟可选的 whitespace 后跟 # 和 1 个或多个字母数字后跟 whitespaces+字母数字(别名)
  • ,?\s*\K - 可选(1 或 0)逗号后跟 0 个或多个白色 space 后跟 \K 强制引擎忽略整段文字匹配得如此之好
  • (?!(?:\w+ )?\bwhere\b) - 限制性前瞻,我们禁止下一个或下一个单词之后的单词等于 where
  • ([\w ]+) - 我们的匹配项,1 个或多个字母数字或 space(可以替换为 [\w\h]+
  • (?=[^w]*(?:\bw(?!here\b)[^w]*)*\bwhere\b) - 尾部边界:必须有除 where 以外的文本,直到第一个 where.