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

kq0g1dla  于 2023-08-08  发布在  其他
关注(0)|答案(5)|浏览(122)

将以下语句作为字符串给定

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

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

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本身的字符串。

i1icjdpr

i1icjdpr1#

如果你的语句总是使用相同的格式,你可以使用一些基本的字符串操作和ast.literal_eval来计算值。请注意,这也将以int,str和float类型的值结束。

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}

mcvgt66p

mcvgt66p2#

为什么要和这些丑陋的黑客搞在一起?让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:",您将获得持久存储。

tkqqtvp1

tkqqtvp13#

好吧,这并不漂亮,但假设你处理的字符串总是一个插入语句(基于它们的特征),这应该可以工作:

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

# if it will always be an insert statement, the following will work.
par1 = stmt[stmt.find("(") + 1:stmt.find(") values")]
par2 = stmt[stmt.find("values (") + 8:-2]

par1_list = par1.split(",")
par2_list = par2.split(",")

d = dict(zip(par1_list, par2_list))

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

字符串
如果你有其他的插入语句,请尝试这个,并告诉我它是否有效。- 谢谢-谢谢

gwbalxhn

gwbalxhn4#

如果你真的想这样做,你的正则表达式最终会因为 * Assert表达式 * 而变得复杂:
不必按'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解决方案

jv2fixgn

jv2fixgn5#

使用吹代码并享受它。

import re
import ast

def ParseInsert(sql):
    cols, values = re.split("values", sql.rstrip(";"), flags=re.IGNORECASE)
    cols = cols.strip(" ").rstrip(")").partition("(")[2].rstrip(")").split(",")
    cols = [x.strip(" ").strip("`").strip("'").lstrip("[").rstrip("]") for x in cols]
    values = values.strip(" ")
    d = dict(zip(cols, ast.literal_eval(values)))
    return d

sqls = [
    "INSERT INTO TBL1(Name,Age)VALUES('Jon',10)",
    "INSERT INTO TBL1 (Name, Age) VALUES ('Jon', 10)",
    "INSERT INTO TBL1 ( Name , Age ) VALUES ( 'Jon' , 10 )",
    "INSERT INTO [TBL1] ( [Name] , [Age] ) VALUES ( 'Jon' , 10 )",
    "INSERT INTO 'TBL1' ( 'Name' , 'Age' ) VALUES ( 'Jon' , 10 )",
    "INSERT INTO `TBL1` ( `Name` , `Age` ) VALUES ( 'Jon' , 10 )"
]

for sql in sqls:
    print(sql)
    print(ParseInsert(sql))
    print()

字符串

输出:

INSERT INTO TBL1(Name,Age)VALUES('Jon',10)
{'Name': 'Jon', 'Age': 10}

INSERT INTO TBL1 (Name, Age) VALUES ('Jon', 10)
{'Name': 'Jon', 'Age': 10}

INSERT INTO TBL1 ( Name , Age ) VALUES ( 'Jon' , 10 )
{'Name': 'Jon', 'Age': 10}

INSERT INTO [TBL1] ( [Name] , [Age] ) VALUES ( 'Jon' , 10 )
{'Name': 'Jon', 'Age': 10}

INSERT INTO 'TBL1' ( 'Name' , 'Age' ) VALUES ( 'Jon' , 10 )
{'Name': 'Jon', 'Age': 10}

INSERT INTO `TBL1` ( `Name` , `Age` ) VALUES ( 'Jon' , 10 )
{'Name': 'Jon', 'Age': 10}

相关问题