简体   繁体   English

在python中将单引号替换为双引号,以便与插入数据库一起使用

[英]Replace single quotes with double quotes in python, for use with insert into database

Was wondering whether anyone has a clever solution for fixing bad insert statements in Python, exported by a not so clever program. 想知道是否有人有一个聪明的解决方案来修复由不太聪明的程序导出的Python中的错误插入语句。 It didn't add two single quotes for strings with a single quote in the string. 它没有为字符串添加两个单引号,并且在字符串中添加了单引号。 To make it a bit easier all the values being inserted are strings. 为了更容易一点,所有要插入的值都是字符串。

So it has: 因此它具有:

INSERT INTO addresses VALUES ('1','1','CUCKOO'S NEST','CUCKOO'S NEST STREET');

instead of: 代替:

INSERT INTO addresses VALUES ('1','1','CUCKOO''S NEST','CUCKOO''S NEST STREET');

Obviously there are multiple lines of this and I don't want to replace the enclosing single quotes as well. 显然,有很多行,而且我也不想替换封闭的单引号。

Was thinking of using split and join, but I'm not sure how to easily update the split values while looping in a loop. 曾经考虑使用split和join,但是我不确定在循环时如何轻松地更新split值。 Sorry I'm a noob. 抱歉,我是菜鸟。 Something like the below, where I'm not sure how to do #update bit 如下所示,我不确定如何执行#update位

import sys

fileIN = open('a.sql', "r")
line = fileIN.readline()

while line:
   bits = line.split("','")
   for bit in bits:
      if bit.find("'") > -1:
         #update bit
   line_out = "','".join(bits)      
   sys.stdout.write(line_out)
   line = fileIN.readline()

Thanks 谢谢

Based on katrielalex's suggestion, how about this: 根据katrielalex的建议,如何处理:

>>> import re
>>> s = "INSERT INTO addresses VALUES ('1','1','CUCKOO'S NEST','CUCKOO'S NEST STREET');"
>>> def repl(m):
    if m.group(1) in ('(', ',') or m.group(2) in (',', ')'):
        return m.group(0)
    return m.group(1) + "''" + m.group(2)

>>> re.sub("(.)'(.)", repl, s)
"INSERT INTO addresses VALUES ('1','1','CUCKOO''S NEST','CUCKOO''S NEST STREET');"

and if you're into negative lookbehind assertions, this is the headache inducing pure regex version: 如果您对断言的看法感到反感,那就是令人头痛的纯正则表达式版本:

re.sub("((?<![(,])'(?![,)]))", "''", s)
while line:
    # Restrain line2 to inside parentheses
    line1, rest = line.split('(')
    line2, line3 = rest.split(')')
    # A bit more cleaner
    new_bits = []
    for bit in line2.split(','):
        # Remove border ' characters
        bit = bit[1:-1]
        # Duplicate the ones inside
        if "'" in bit:
            bit = bit.replace("'", "''")
        # Re-add border '
        new_bits.append("'" + bit + "'")
   sys.stdout.write(line1 + '(' + ','.join(new_bits + ')' + line3)
   line = fileIN.readline()

Warning: This depends way too much on the formatting of the SQL statement. 警告:这取决于太多的SQL语句的格式。 However, if your input is only ever going to have the format "statements (params) end" then this will work every time. 但是,如果您的输入仅具有“语句(参数)结尾”格式,则每次都可以使用。

import sys

fileIN = open('a.sql', "r")
line = fileIN.readline()

while line:
    #split out the parameters (between the ()'s)
    start, temp = line.split("(")
    params, end = temp.split(")")

    #replace the "'"s in the parameters (without the start and end quote)
    newParams = "','".join([x.replace("'", "''") for x in params[1:-1].split("','")])

    #join the statement back together
    line_out = start + "('" + newParams + "')" + end

    #next line
    sys.stdout.write(line_out)
    line = fileIN.readline()

Explanation: 说明:

  1. Split the string into 3 parts: The query start, the parameters, and the end. 将字符串分为3部分:查询开始,参数和结束。
  2. The generator takes the parameters (without the starting/ending ' s), splits it on ',' , and, for every element in the list the split generates (the individual data entries), replaces the ' s with '' s. 生成器获取参数(不包含开始/结尾' s),将其分割为',' ,然后,对于分割生成的列表中的每个元素(各个数据条目),将“ '替换为''
  3. The last line then joins the query start, the new params (with the parenthesis and quotes that were removed previously), and the end of the statement. 然后,最后一行将查询的开头,新的参数(带括号和引号的先前已删除)和语句的末尾连接起来。

Another answer: 另一个答案:

a = "INSERT INTO addresses VALUES ('1','1','CUCKOO'S NEST','CUCKOO'S NEST STREET');"
open_par = a.find("(")
close_par = a.find(")")
b = a[open_par+1:close_par]
c = b.split(",")
d = map(lambda x: '"' + x.strip().strip("'") + '"',c)
result = a[:open_par+1] + ",".join(d) + a[close_par:]

Went with: 与:

import sys
import re

def repl(m):
    if m.group(1) in ('(', ',') or m.group(2) in (',', ')'):
        return m.group(0)
    return m.group(1) + "''" + m.group(2)

fileIN = open('a.sql', "r")
line = fileIN.readline()

while line:
    line_out = re.sub("(.)'(.)", repl, line)
    sys.stdout.write(line_out)
    # Next line.
    line = fileIN.readline()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM