2017-01-09 176 views
0

某處我是一個白癡,但我找不到在哪裏。Python:相同的字符串切片,兩個不同的結果

我正在通過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 

左括號仍然在這裏,即使我使用find()方法以同樣的方式的結果,將一個開放的括號位置作爲片的起點,兩次。

下面是代碼:

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'?它看起來很像一個python元組的'repr'。也許這些數據是作爲一個元組來提供的,這將使得處理它變得毫無意義。對於你的問題,你正在爲'dbErrorString'指定'strippedString',但是在實際的切片中使用'errorString'而不是'strippedString'。 –

+0

我想剝離外部左括號和右括號以及它們之外的所有內容。原始字符串是從ODBC返回的錯誤字符串,因爲在數據庫函數內遇到錯誤情況。該字符串不是來自Python並且不在元組中。 這項工作的目標是隻返回包含在這個長長的gobbledygook內的錯誤信息:「錯誤:收費不正確的狀態刪除」。 –

回答

1

它看起來像這樣一行:

dbErrorString = errorString[openParenLocation + 1:closeParenLocation]

應改爲:

dbErrorString = strippedString[openParenLocation + 1:closeParenLocation]

+0

如果您確實想要再次使用原始的errorString,那麼您需要考慮第一個條帶的索引更改,但是由於您覆蓋了第一個openParenLocation,因此您需要對此進行一些重構。 –

+0

請參閱?我知道這是我做的一些愚蠢的事情。非常感謝! –

0

鑑於您的字符串看起來像Python語法,都可以使用標準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直接使串入Python對象,它描述。它就像內置的eval,但從安全角度來看是安全的,因爲它不會評估任何不是字面的內容(因此,不會執行任何惡意的errorString內容)。

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

+0

我不在乎這個解決方案。我們不是Python專家,重要的是每個看着我的代碼的人都能夠理解它。我不知道抽象語法樹是什麼,我不認爲問我或我的同事學習這個概念以理解我的代碼是個好主意。 –

+0

'eval(errorString)'會做什麼? –

+0

'eval(errorString)'將返回'errorString'似乎描述的嵌套元組對象。它可以像其他任何Python對象一樣被操縱。對你的例子進行試用並安全地使用它是安全的,但在編輯的答案中看到警告。 – jez

相關問題