<p>在这里不能使用正则表达式,因为SQL语法不形成可以与Python<code>re</code>引擎匹配的正则模式。实际上,您必须将字符串解析为令牌流或语法树;毕竟,<code>SUM(...)</code>可以包含大量语法,包括子选择。在</p>
<p><a href="https://sqlparse.readthedocs.io/" rel="nofollow noreferrer">^{<cd3>} library</a>可以这样做,即使它是<a href="https://stackoverflow.com/questions/54982118/parse-case-when-statements-with-sqlparse/54986493#54986493">bit underdocumented and not that friendly to external uses</a>。在</p>
<p>重新使用我在链接到的另一篇文章中定义的<code>walk_tokens</code>函数:</p>
<pre><code>from collections import deque
from sqlparse.sql import TokenList
def walk_tokens(token):
queue = deque([token])
while queue:
token = queue.popleft()
if isinstance(token, TokenList):
queue.extend(token)
yield token
</code></pre>
<p>从<code>SELECT</code>标识符列表中提取最后一个元素是:</p>
^{pr2}$
<p>演示:</p>
<pre><code>>>> sql = '''\
... SUM(case when(A.money-B.money>1000
... and A.unixtime-B.unixtime<=890769
... and B.col10 = "A"
... and B.col11 = "12"
... and B.col12 = "V") then 10
... end) as finalCond0,
... MAX(case when(A.money-B.money<0
... and A.unixtime-B.unixtime<=6786000
... and B.cond1 = "A"
... and B.cond2 = "4321"
... and B.cond3 in ("E", "F", "G")) then A.col10
... end) as finalCond1,
... SUM(case when(A.money-B.money>0
... and A.unixtime-B.unixtime<=6786000
... and B.cond1 = "A"
... and B.cond2 = "1234"
... and B.cond3 in ("A", "B", "C")) then 2
... end) as finalCond2
... '''
>>> tokens = sqlparse.parse(sql)[0]
>>> for tok in walk_tokens(tokens):
... if isinstance(tok, IdentifierList):
... # iterate to leave the last assigned to `identifier`
... for identifier in tok.get_identifiers():
... pass
... break
...
>>> print(identifier)
SUM(case when(A.money-B.money>0
and A.unixtime-B.unixtime<=6786000
and B.cond1 = "A"
and B.cond2 = "1234"
and B.cond3 in ("A", "B", "C")) then 2
end) as finalCond2
</code></pre>
<p><code>identifier</code>是一个<code>sqlparse.sql.Identifier</code>实例,但是再次将其转换为字符串(这是<code>print()</code>所做的,或者您可以只使用<code>str()</code>)为该部分再次提供输入SQL字符串。在</p>