2017-01-09 1 views
0

어딘가에 나는 바보가되고 있지만 어디서 찾을 수 없습니다.파이썬 : 동일한 문자열 분할, 두 가지 결과

저는 ODBC를 통해 PostgreSQL 데이터베이스를 사용하는 Python 스크립트를 실행하고 있습니다. 데이터베이스 예외 메시지에서 의미있는 부분을 추출하려고합니다. 다음은 가독성을 위해 줄 바꿈이 추가 된 원시 메시지입니다.

(-2147352567, 'Exception occurred.', (0, 'Microsoft OLE DB Provider for ODBC Drivers', 
'ERROR: Charge not in a correct status to delete;\nError while executing the query', 
None, 0, -2147467259), None) 

이 문자열에는 두 세트의 괄호가 있습니다. 먼저, 바깥 쪽의 위치를 ​​찾아서 잘라 낸다. 이것은 예상 된 결과 제공 : 나는 동일한 코드를 말할 수있는 지금까지 사용, 그리고

-2147352567, 'Exception occurred.', (0, 'Microsoft OLE DB Provider for ODBC Drivers', 
'ERROR: Charge not in a correct status to delete;\nError while executing the query', 
None, 0, -2147467259), None 

을, 나는 그들 이외의 다른 괄호 세트와 모든 것을 벗겨. 이것은이 결과를 제공합니다

(0, 'Microsoft OLE DB Provider for ODBC Drivers', 
'ERROR: Charge not in a correct status to delete;\nError while executing the query', 
None, 0, -214746725 

오픈 괄호 내가 조각의 시작으로 여는 괄호 위치에 하나를 추가, 찾기() 메소드 같은 방식의 결과를 사용하고, 비록 아직 여기있다, 두 번. 여기

코드입니다 :

print (errorString) 
    openParenLocation = errorString.find('(') 
    closeParenLocation = errorString.rfind(')') 
    strippedString = errorString[openParenLocation + 1:closeParenLocation] 
    openParenLocation = strippedString.find('(') 
    closeParenLocation = strippedString.rfind(')') 
    dbErrorString = errorString[openParenLocation + 1:closeParenLocation] 
    print (strippedString) 
    print ("{}, {}".format(openParenLocation, closeParenLocation)) 
    print (dbErrorString) 

그리고 여기에 더 추가 된 라인 원시 출력, 고장입니다 : 훨씬 더 작은 문자열을 사용

(-2147352567, 'Exception occurred.', (0, 'Microsoft OLE DB Provider for ODBC Drivers', 'ERROR: Charge not in a correct status to delete;\nError while executing the query', None, 0, -2147467259), None) 
-2147352567, 'Exception occurred.', (0, 'Microsoft OLE DB Provider for ODBC Drivers', 'ERROR: Charge not in a correct status to delete;\nError while executing the query', None, 0, -2147467259), None 
36, 191 
(0, 'Microsoft OLE DB Provider for ODBC Drivers', 'ERROR: Charge not in a correct status to delete;\nError while executing the query', None, 0, -214746725 

테스트 코드가 예상대로 작동합니다

testString = "(abc(def)ghij)" 
    openParenLocation = testString.find('(') 
    closeParenLocation = testString.rfind(')') 
    strippedTestString = testString[openParenLocation + 1:closeParenLocation] 
    openParenLocation = strippedTestString.find('(') 
    closeParenLocation = strippedTestString.rfind(')') 
    finalTestString = strippedTestString[openParenLocation + 1:closeParenLocation] 

대단히 감사합니다.

+0

Errorstring이 '[openParenLocation + 1 : closeParenLocation]'?? 'openParenLocation + 1 : closeParenLocation'을 사용하여 무엇을하려고합니까? – alfasin

+0

원래 어떻게'errorString'을 얻고 있습니까? 그것은 파이썬 튜플의'repr'와 매우 흡사합니다. 아마도이 데이터는 튜플로 사용할 수 있으므로 처리하기가 쉽지 않습니다. 귀하의 질문에, 당신은'dbErrorString' fron'strippedString'에 대한 색인을 형성하고 있지만'strippedString' 대신에 실제 slicing에서'errorString'을 사용합니다. –

+0

바깥 쪽 괄호와 닫는 괄호 및 그 바깥 쪽 모든 것을 제거하려고합니다.원래 문자열은 데이터베이스 함수 내에서 오류 조건이 발생하여 ODBC에서 리턴 된 오류 문자열입니다. 문자열은 파이썬이 아니며 튜플에 없습니다. 이 작업의 목표는이 긴 이야기에 포함 된 오류 메시지 만 반환하는 것입니다. "오류 : 올바른 상태가 아니기 때문에 삭제할 수 없습니다." –

답변

1

그것은이 줄 모양을 :

dbErrorString = errorString[openParenLocation + 1:closeParenLocation]

대신해야한다 : 당신의 문자열을 파이썬 구문처럼 보이는 것을

dbErrorString = strippedString[openParenLocation + 1:closeParenLocation]

+0

원래의 errorString을 다시 사용하려면 첫 번째 스트립에서 인덱스의 변경 사항을 고려해야하지만 첫 번째 openParenLocation을 덮어 쓰기 때문에이 작업을 수행하려면 일부 리팩토링이 필요합니다. –

+0

참조? 나는 그것이 내가하고있는 바보 같은 짓임을 알았다. 매우 감사합니다! –

0

을 감안할 때, 당신은 표준 ast 라이브러리 모듈을 사용하여 고려했다 이 모든 일을 너에게 해줄거야?

>>> errorString =r"""\ 
(-2147352567, 'Exception occurred.', (0, 'Microsoft OLE DB Provider for ODBC Drivers', 
'ERROR: Charge not in a correct status to delete;\nError while executing the query', 
None, 0, -2147467259), None)""" 

>>> import ast 
>>> a = ast.parse(errorString).body[0].value 
>>> a 
<_ast.Tuple at 0x10802d3d0> 

>>> a.elts[0] 
<_ast.Num at 0x10802d410> 

>>> a.elts[0].n 
-2147352567 

>>> a.elts[1] 
<_ast.Str at 0x10802d450> 

>>> a.elts[1].s 
'Exception occurred.' 

>>> a.elts[2] 
<_ast.Tuple at 0x10802d490> 

>>> # so now lather/rinse repeat: iterate over a.elts[2].elts 

>>> a.elts[3] 
<_ast.Name at 0x10802d650> 

>>> a.elts[3].id 
'None' 

더 간단한 방법은 설명하는 파이썬 객체에 직접 문자열을 설정하는 ast.literal_eval을 사용하는 것입니다. 마치 eval과 비슷하지만 리터럴이 아닌 것을 평가하지 않기 때문에 보안 관점에서는 안전합니다. 따라서 어떤 악의적 인 콘텐츠도 실행되지 않습니다 (errorString).

>>> a = ast.literal_eval(errorString) 
>>> a[0] 
-2147352567 
>>> a[1] 
'Exception occurred.' 
>>> a[2][0] 
0 

+0

나는이 해결책을 걱정하지 않는다. 우리는 여기서 파이썬 전문가가 아니며, 제 코드를 보려하는 모든 사람들이 그것을 이해할 수 있어야합니다. Abstract Syntax Tree가 무엇인지 전혀 알지 못합니다. 제 코드를 이해하기 위해 저 또는 제 동료에게 그 개념을 배우도록 요청하는 것이 좋습니다. –

+0

'eval (errorString)'은 무엇을합니까? –

+0

'eval (errorString)'은 'errorString'이 기술하는 중첩 된 튜플 객체를 반환합니다. 그런 다음 다른 Python 객체처럼 조작 할 수 있습니다. 그것은 당신의 예제에 그것을 밖으로 시도하고 그것으로 놀아도 안전하지만, 편집 된 답변에 경고를 참조하십시오. – jez