2017-01-09 32 views
0

どこか私はばかだが、どこに見つけることができない。Python:同じ文字列のスライス、2つの異なる結果

私は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) 

この文字列には2組の括弧があることに注意してください。まず、外側の位置を見つけてスライスします。私の知る限り、私は括弧とその外側のすべての他のセットを取り除き、同じコードを言うことができるように使用して、その後

-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 

開き括弧は、私は、スライスの開始と開き括弧の位置に1を加え、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' fron' strippedString'のインデックスを作成していますが、 'strippedString'の代わりに実際のスライシングで' errorString'を使います。 –

+0

外側のかっこと閉じ括弧、および外側のすべてを取り除こうとしています。元の文字列は、データベース関数内でエラー状態が発生したためにODBCから返されたエラー文字列です。文字列はPythonからではなく、タプルではありません。 この作業の目標は、この長いゴブリンク内に含まれているエラーメッセージだけを返すことです。「ERROR:削除する正しい状態ではない」。 –

答えて

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' 

でも簡単な方法は、それが記述するPythonオブジェクトに直接文字列をオンにするast.literal_evalを使用することです。組み込みのevalと似ていますが、リテラルでないものは評価されないため、セキュリティの観点からは安全です(したがって、悪質なコンテンツは実行されません)。

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

関連する問題