1

それほど賢くないプログラムによってエクスポートされた、Pythonの不正な挿入ステートメントを修正するための賢い解決策があるかどうか疑問に思っていました。文字列に一重引用符が含まれる文字列には、2つの一重引用符は追加されませんでした。少し簡単にするために、挿入されるすべての値は文字列です。

だからそれは持っています:

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

それ以外の:

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

明らかに、これには複数の行があり、囲んでいる一重引用符も置き換えたくありません。

分割と結合を使用することを考えていましたが、ループでループしているときに分割値を簡単に更新する方法がわかりません。申し訳ありませんが、私は初心者です。以下のようなもので、#updatebitの実行方法がわかりません

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()

ありがとう

4

5 に答える 5

7

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');"

そして、あなたが否定的な後ろ向きの主張に興味があるなら、これは純粋な正規表現バージョンを誘発する頭痛です:

re.sub("((?<![(,])'(?![,)]))", "''", s)
于 2012-07-23T12:19:37.997 に答える
0
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()
于 2012-07-23T12:11:02.930 に答える
0

警告:これは、SQLステートメントのフォーマットに大きく依存します。ただし、入力の形式が「ステートメント(パラメーター)終了」のみである場合、これは毎回機能します。

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()

説明:

  1. 文字列を3つの部分に分割します。クエリの開始、パラメータ、および終了です。
  2. ジェネレーターはパラメーター(開始/終了'sなし)を受け取り、それをで分割し','、分割が生成するリスト内のすべての要素(個々のデータエントリ)について、'sを''sに置き換えます。
  3. 最後の行は、クエリの開始、新しいパラメータ(以前に削除された括弧と引用符を含む)、およびステートメントの終わりを結合します。
于 2012-07-23T12:51:09.527 に答える
0

別の答え:

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:]
于 2012-07-23T14:05:03.107 に答える
0

一緒に行きました:

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()
于 2012-07-24T10:01:44.743 に答える