将SQL插入语句拆分为键值对

时间:2016-06-17 12:30:46

标签: python regex

将以下语句作为字符串

stmt = "insert into table (col1, col2, col3) values (100, '() string with parantheses ()', 2.3);"

我试图找到一个正则表达式(或任何其他方式,如果有一个更好的表达式)将该字符串拆分为列表["(col1, col2, col3)", "(100, '() string with parantheses ()', 2.3)"],以便我以后可以用列名和值填充一个dicionary

d = { "col1" : "100", "col2" : "'() string with parantheses ()'", "col3" : "2.3" }

到目前为止,我有以下解决方案,我不喜欢(或者我相信有一个解决方案使用正则表达式只做同样的事情)。

re.findall("\([^\r\n]*\)", stmt)[0].split("values")
# from here on I would have to parse the two strings and fill a dict

我无法找到解决方案,我不必仅使用正则表达式将字符串拆分为'values'。我的主要问题是值的第二个parantheses字符串可能包含字符串中的parantheses。

4 个答案:

答案 0 :(得分:2)

如果您的语句始终采用相同的格式,则可以使用一些基本的字符串操作和ast.literal_eval来评估值...请注意,这也将最终得到具有int,str和类型的值。浮。

import ast
import csv

stmt = "insert into table (col1, col2, col3) values (100, '() string with parantheses ()', 2.3);"
pre, values = stmt.rstrip(';').partition(' values ')[::2]
cols = pre.partition('(')[2]
d = dict(zip(cols.rstrip(')').split(', '), ast.literal_eval(values)))

这会给你:

{'col1': 100, 'col2': '() string with parantheses ()', 'col3': 2.3}

答案 1 :(得分:2)

为什么要搞乱这些丑陋的黑客?让SQL解析SQL。这是一个将任何insert语句转换为元组的完整程序:

my_insert = """insert into some_table (col1, col2, col3) values (100, 
                                        '() string with parantheses ()', 2.3);"""

import sqlite3
conn = sqlite3.connect(":memory:")  
conn.execute("create table some_table (col1, col2, col3)")
conn.execute(my_insert)
parsed_rows = list(conn.execute("select * from some_table"))
conn.close()

print(parsed_rows)
# Output:
[(100, '() string with parantheses ()', 2.3)]

当然,您可能还需要考虑将数据实际存储在数据库中,而不是现在计划用它们执行的任何操作。在这种情况下,在建立连接时使用文件名而不是":memory:",并且您将获得持久存储。

答案 2 :(得分:0)

嗯,这并不漂亮,但假设你使用的字符串将始终是一个插入语句(基于它们的特性),这应该有效:

TextRenderer.MeasureText

如果您有其他插入语句,请尝试此操作并告诉我它是否有效。 谢谢。

答案 3 :(得分:0)

如果你真的想要这个,你的正则表达式最终会因断言表达式而变得复杂:

  

不必将字符串拆分为'values'

match = re.findall("""(?<!\') # No preceeding ' before (
                     \(
                     (?!\))  # A closing parenthesis must not follow a (
                     [^\r\n]*?
                     (?<!\() # An opening parenthesis must not precede a )
                     \)
                     (?!\')  # No following ' immedaitely after )
                     """, stmt, re.VERBOSE)
# ['(col1, col2, col3)', "(100, '() string with parantheses ()', 2.3)"]

r = [o.strip() for i in match for o in i[1:-1].split(',')]
d = dict(zip(*r))
# {'col1': '100', 'col3': '2.3', 'col2': "'() string with parantheses ()'"}

您应该使用SQL解决方案以获得正确性