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

3

我有一个查询,想要获取 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 ...)

你期望的输出是什么? - Avinash Raj
不确定,但我猜你可以尝试\bfrom([^w]*(?:\bw(?!here\b)[^w]*)*)where - Wiktor Stribiżew
如果您不想匹配以from开头的任何子字符串后跟#,我宁愿使用\bfrom(?!\s*#)([^w]*(?:\bw(?!here\b)[^w]*)*)where - Wiktor Stribiżew
@bobblebubble,我需要查询和子查询中的所有表名,一个查询可能有多个带别名的表。 - Abdul Rehman
1
@Bsienn 感谢您的回答!我的正则表达式是相反的。它是用来排除子查询中的表名的。最好在问题中尽可能准确地描述问题。 - bobble bubble
显示剩余2条评论
1个回答

3
您可以使用以下正则表达式:
\bfrom\b(?!\s*#)([^w]*(?:\bw(?!here\b)[^w]*)*)\bwhere\b

请查看正则表达式演示

如果需要区分大小写,请选中“区分大小写”选项。

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

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

请查看另一个演示和结果屏幕:

输入图像描述

正则表达式分解:

  • (?<=\bfrom\b) - 检查下一个单词之前是否有整个单词 from ...
  • (?!\s*#) - 确保没有 0 或更多空格后跟 #
  • ([^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(作为一个完整的单词),后面是可选的空格,然后是#和1个或多个字母数字,随后是空格+字母数字(别名)
  • ,?\s*\K - 可选的(1或0)逗号,后面是0个或多个空格,随后是\K强制引擎省略到目前为止匹配的整个文本块
  • (?!(?:\w+ )?\bwhere\b) - 限制性前瞻,我们禁止下一个单词或下一个单词之后的单词与where相等
  • ([\w ]+) - 我们的匹配项,1个或多个字母数字或空格(可以替换为[\w\h]+
  • (?=[^w]*(?:\bw(?!here\b)[^w]*)*\bwhere\b) - 尾部边界:第一个where之前必须有除where以外的文本。

1
这项任务不是基础级别的。你需要学习正向预查、否定字符类、单词边界、展开循环等知识...当然,你可以直接使用 (?s)from.*?where,但如果文档太长,在其中间包含了 nowhere,该怎么办呢?我试图想出最安全的正则表达式,这需要大量的正则表达式知识。 - Wiktor Stribiżew
1
我在第一个正则表达式中添加了单词边界。我建议您在regexone.com上完成所有课程,阅读regular-expressions.inforegex SO tag description(其中包含许多其他优秀的在线资源)以及社区SO帖子What does the regex mean。此外,rexegg.com是一个非常好的正则表达式学习网站(使用参考资料)。 - Wiktor Stribiżew
1
这解决了问题。谢谢。非常感谢你,你帮了我很多,这些教程也很棒。谢谢。 - Abdul Rehman
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接