2017-01-09 116 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

相关问题