3

基本的な式(のような)を取得するxmlファイルを解析していますid*10+2。私がやろうとしているのは、式を評価して実際に値を取得することです。そうするために、私はeval()非常にうまく機能する方法を使用します。

唯一のことは、数字が実際には16進数であることです。すべての 16 進数の前に「0x」を付けると、このeval()方法はうまく機能しますが、それを行う方法を見つけることができず、ここでも同様の質問を見つけることができませんでした。それはどのようにきれいな方法で行われますか?

4

4 に答える 4

4

モジュールを使用しreます。

>>> import re
>>> re.sub(r'([\dA-F]+)', r'0x\1', 'id*A+2')
'id*0xA+0x2'
>>> eval(re.sub(r'([\dA-F]+)', r'0x\1', 'CAFE+BABE'))
99772

ただし、 への無効な入力では機能しないことに注意してくださいeval。また、使用には多くのリスクevalがあります。

16 進数に小文字が含まれている場合は、次のように使用できます。

>>> re.sub(r'(?<!i)([\da-fA-F]+)', r'0x\1', 'id*a+b')
'id*0xa+0xb'

これは、否定の後読みアサーションを使用して、文字iが変換しようとしているセクションの前にないことを保証'id''i0xd'ます(変数iが.IId

于 2013-05-03T08:56:52.200 に答える
0

1 つのオプションは、parserモジュールを使用することです。

import parser, token, re

def hexify(ast):
    if not isinstance(ast, list):
        return ast
    if ast[0] in (token.NAME, token.NUMBER) and re.match('[0-9a-fA-F]+$', ast[1]):
        return [token.NUMBER, '0x' + ast[1]]
    return map(hexify, ast)

def hexified_eval(expr, *args):
    ast = parser.sequence2st(hexify(parser.expr(expr).tolist()))
    return eval(ast.compile(), *args)

>>> hexified_eval('id*10 + BABE', {'id':0xcafe})
567466

これは、名前または数値として明確に識別された (そして 16 進数のように見える) トークンのみを置き換えようとするという点で、正規表現ソリューションよりもいくらかクリーンです。また、( に置き換えられid*10 + len('BABE')ません)などのより一般的な python 式も正しく処理します。'BABE''0xBABE'

OTOH、正規表現ソリューションはよりシンプルであり、とにかく対処する必要があるすべてのケースをカバーする可能性があります.

于 2013-05-03T10:03:29.190 に答える
0

式を個々の数値に解析できる場合は、int 関数を使用することをお勧めします。

>>> int("CAFE", 16)
51966
于 2013-05-03T09:51:22.210 に答える
0

注意してくださいeval!信頼できない入力では使用しないでください。

単純な算術演算だけなら、カスタム パーサーを使用します (世の中にはたくさんの例があります)。また、パーサー ジェネレーター (flex/bison、antlr など) を使用するスキルは便利ですが、すぐに忘れてしまいます。ので、リフレッシュしたり、学んだりする良い機会になるかもしれません。

于 2013-05-03T09:53:47.680 に答える