【发布时间】:2021-12-06 12:45:17
【问题描述】:
我想捕获整个子查询,无论中间是否有连接或子字符串函数(即忽略子查询中的另一个括号打开和关闭。(a)我们不想将“加入”捕获为一个单词 (b) “alias2” 不会总是跟在“join”之后,它可以是任何东西(单词边界、空格或“join”单词)。
案例 1:select 中没有 concat 或 sub-string 函数
-
在:
(select t1.col1 as alias1 from db.tb where t1.col1='val1') alias2 join -
输出:
(select t1.col1 as alias1 from db.tb where t1.col1='val1') alias2
案例 2:select 中的 Concat 函数
-
在:
(select concat(t1.col1, t2.col1, t3.col1) as alias1 from db.tb where t1.col1='val1') alias2 join -
输出:
(select concat(t1.col1, t2.col1, t3.col1) as alias1 from db.tb where t1.col1='val1') alias2
我尝试过的:
方法一:re.findall('\(select.*?\)\s[a-zA-Z0-9_]+', input statement)
方法 2:如 @TheFourthBird 建议的那样
import re
pat1 = '\(select.*?\)\s[a-zA-Z0-9_]+'
pat2 = "\(select [^()]*(?:(\((?>[^()]+|(?1))*\)))?[^()]*\)[^()\n]+"
string1 = "(select t1.col1 as alias1 from db.tb where t1.col1='val1') alias2"
string2 = "(select concat(t1.col1, t2.col1, t3.col1) as alias1 from db.tb where t1.col1='val1') alias2"
print(re.findall(pat1, string1))
print(re.findall(pat1, string2))
import regex as re
print(re.findall(pat2, string1))
print(re.findall(pat2, string2))
pattern = re.compile(pat2, re.UNICODE)
print([match.group(0) for match in pattern.finditer(string2)])
输出:
["(select t1.col1 as alias1 from db.tb where t1.col1='val1') alias2"]
['(select concat(t1.col1, t2.col1, t3.col1) as']
['']
['(t1.col1, t2.col1, t3.col1)']
["(select concat(t1.col1, t2.col1, t3.col1) as alias1 from db.tb where t1.col1='val1') alias2 join "]
上述方法有什么问题:
-
方法 1:适用于案例 1,但不适用于案例 2。
-
方法 2:仍然行不通!但是,
["(select concat(t1.col1, t2.col1, t3.col1) as alias1 from db.tb where t1.col1='val1') alias2 join "]是最符合预期的。但是,它不应该捕获 alias2 旁边的内容。
请帮帮我!
【问题讨论】:
-
你安装了还是安装了pypi.org/project/regex?
-
你有我建议的模式的旧版本,应该是like this
\(select [^()]*(?:(\((?>[^()]+|(?1))*\)))?[^()]*\)\s[a-zA-Z0-9_]+ -
这与旧版本无关。模式变了!!让我看看它现在是否有效。
-
现在使用您现在建议的模式适用于上述示例。谢谢@Thefourthbird。
标签: mysql python-3.x regex