2013-03-11 2 views
-2

У меня есть тонны линий, как это:питона и строка извлечения

13480 AAA BBB CCC 

Я хотел бы, чтобы преобразовать их с помощью питона в чем-то вроде:

SELECT XX FROM YY WHERE SOUNDEX("AAA BBB CCC")=FIELD1 AND CP="13480" 

Зная, что «AAA BBB CCC» является город , так что это может быть «AAA BBB CCC», «AAA BBB», «AAA-BBB-CCC», «AAA», «L'AAA», «D'AAA BBB», «D'AAA..». Ну, конец строки сразу после номера - это название города.

Так большой файл containings строки вроде:

06260 Puget Théniers 
06620 Bar sur Loup (Le) 
06640 SAINT JEANNET 
06640 Saint Jeannet 
06660 AURON 
06660 SAINT ETIENNE DE TINEE 
06660 Saint Etienne de Tinée 
06670 Levens 
06710 Touët sur Var 
06750 ANDON 
06750 Thorenc 

конца бы в чем-то вроде

SOUNDEX("Puget Théniers") AND CP="06260" 
SOUNDEX("Bar sur Loup (Le)") AND CP="06620" 
SOUNDEX("SAINT JEANNET") AND CP="06640" 
SOUNDEX("Saint Jeannet") AND CP="06640" 
SOUNDEX("AURON") AND CP="06660" 
SOUNDEX("SAINT ETIENNE DE TINEE") AND CP="06660" 
SOUNDEX("Saint Etienne de Tinée") AND CP="06660" 
SOUNDEX("Levens") AND CP="06670" 
SOUNDEX("Touët sur Var") AND CP="06710" 
SOUNDEX("ANDON") AND CP="06750" 
SOUNDEX("Thorenc") AND CP="06750" 

Что является лучшим/чистым способом начать?

Я знаю, что могу сделать это в bash shellusing регулярных выражений, но я уже сделал большой парсер в python, который выводит строки, подобные этому. Поэтому я хотел бы закончить все это на Python, и поэтому я ищу чистый код & для некоторых объяснений, потому что у меня может быть много «фильтров», подобных этому в будущем.

[обновление] 13480 - это то, что всегда должно быть числами, а если нет, то следует возбуждать исключение.

+2

Используйте параметры SQL, которые поддерживаются вашей библиотекой соединений SQL. Do * not * попытайтесь вставить значения в SQL-запросы, подобные этому, с форматированием строки. –

+5

И это не вопрос. что вы пробовали и с какими проблемами вы столкнулись? Я бы ожидал, что пользователь с 4k-репутацией узнает, что мы можем помочь вам с практическими вопросами, а не с вопросами «дайте мне-код». –

+0

Начиная с регулярного выражения, вы сможете легко адаптировать решение к различным входам. – eyquem

ответ

2

Попробуйте это (более сложный):

import re 
str = "13480 D'AAA-BBB CCC..." 
result = re.search("([\d]+)\s([\w\s\x27\x2E\x2C\x2D]+)",str) 

print(result.group(1)) # will print "13480" 
print(result.group(2)) # will print "D'AAA-BBB CCC..." 

супер простое решение:

str = "13480 D'AAA-BBB CCC..." 
result = str.split(' ',1) 

print(result[0]) # will print "13480" 
print(result[1]) # will print "D'AAA-BBB CCC..." 

Теперь вы должны использовать результаты группы (1) и группы (2) или результат [0] и результат [1] для создания SQL-запроса. Но я советую вам использовать параметризованный запрос вместо простых строковых операций (чтобы избежать SQL-инъекции).

+0

+1 для предупреждения sql-injection –

+0

Это не может быть SQL-инъекция, поскольку она уже дезинформирована с помощью 'htmlentities()'. Спасибо за предупреждение –

+0

Я только что обновил свой вопрос: возможно, с вашим решением, что «AAA BBB CCC "может содержать любой символ (как в моем обновленном вопросе)? –

2
'SELECT XX FROM YY WHERE SOUNDEX("{1} {2} {3}")=FIELD1 AND CP="{0}"'\ 
    .format(*'13480 AAA BBB CCC'.split()) 

Это один лайнер будет делать, вы можете также использовать некоторые regular expression.

Но это определенно не что вы хотите использовать. Как Martijn прокомментировал, вы не должны строить свои выражения SQL вручную. Используйте обертку вокруг SQL базы - MySQLdb или универсальный sqlalchemy (вы будете в конечном итоге с последним в конце концов)

С sqlalchemy вы бы в конечном итоге с чем-то вроде этого:

input_id, input_fields = input_line.split(maxsplit=1) 
selection = (session.query(YY_Table) 
        .filter(YY_Table.field1=input_fields) 
        .filter(YY_Table.cp=input_id)) 

(Все это при условии ., что вы делаете правильный сценарий Если вы пишете один код одноразового, что массаж в вашей базе данных, то не стесняйтесь использовать split, RegEx или даже VIM сценариев)

+0

Здравствуйте. Я удалил свой ответ, потому что кто-то перевел с французского на английский (не настоящая проблема), но изменил содержание того, что я сказал. Тем не менее, был комментарий от вас, которого я не понял: «« обнаружено устройство »_. Что это значит? – eyquem

+0

Это была просто шутка для Mac-пользователей, без обид :) http: //en.wikipedia. org/wiki/Bonjour_ (ПО) –

+0

ОК, спасибо. Я не чувствовал себя оскорбленным. Я не anglophone, и иногда мне интересно о фразах, которые я не понимаю. - Я удалю эти комментарии через некоторое время. – eyquem

0
# Replace yourdbms with the library of your choice 
# Be sure to use the library's tokens (%s, ?, etc.) 

import yourdbms 

sql = """ 
    SELECT XX FROM YY 
    WHERE SOUNDEX(%s)=FIELD1 AND 
      CP=%s 
    """ 
conx = yourdbms.connect(your_db_info) 
cursor = conx.cursor() 
with open('path/to/yourfile', 'r') as f: 
    for line in f: 
     # Get the params without regex 
     pos = line.find(' ') 
     params = line[pos+1:], int(line[:pos]) 
     cursor.execute(sql, params) 
     do_something_with(cursor) 
cursor.close() 
conx.close() 
+0

Простите, что я не могу выразить себя правильно, вопрос о python и regexp, не имеет ничего общего с SQL. Я уточню свой вопрос, чтобы яснее. Еще раз извините. –

+0

Вам не нужны регулярные выражения для решения вашей проблемы. Вы вводите ненужные накладные расходы и подвергаете себя инъекции SQL. Исходя из вашего обновленного вопроса, это можно решить довольно легко. Я уточню свой ответ. Если вы просто используете надуманный пример, я бы выбрал менее «чувствительную» тему :) – pyrospade

0

Вы можете просто разделить эти строки на первом пространстве:

for line in inputfile: 
    code, town = line.strip().split(None, 1) 

Теперь вы можете дополнительно обрабатывать эту информацию. Если вы хотите использовать это для запроса базы данных, я бы не генерировать текст запроса SQL. Вместо того, чтобы использовать параметры SQL:

cursor.select('SELECT XX FROM YY WHERE SOUNDEX(?)=FIELD1 AND CP=?', (town, code)) 

Это имеет несколько преимуществ:

  1. Вам не придется беспокоиться о том, как правильно бежать параметров. Это важно при предотвращении атак SQL-инъекций, а также при обработке произвольных данных из файла, где входные данные потенциально могут содержать специальные символы, специфичные для SQL.
  2. База данных предоставлена ​​возможность подготовить инструкцию, создав план запроса, который может быть повторно использован для будущих запросов. Если вы делаете много таких запросов, это имеет огромное значение.
Смежные вопросы