4

私は次のような形式の行を含むファイルを読んでいます

[ 0 ] L= 9 (D) R= 14 (D) p= 0.0347222 e= 10 n= 34

私はMatlabコードがによって与えられたこのファイルを読むのを見ました

[I,L,Ls,R,Rs,p,e,n] = textread(f1,'[ %u ] L= %u%s R= %u%s p= %n e=%u n=%u')

このファイルをPythonで読みたいです。私が知っているのは正規表現だけです。この行の一部でも読むと、次のようなものになります。

re.compile('\s*\[\s*(?P<id>\d+)\s*\]\s*L\s*=\s*(?P<Lint>\d+)\s*\((?P<Ltype>[DG])\)\s*R\s*=\s*(?P<Rint>\d+)\s*')

これは醜いです!Pythonでこれを行う簡単な方法はありますか?

4

4 に答える 4

4

エスケープ/置換を使用して正規表現を作成することで、正規表現を読みやすくすることができます...

number = "([-+0-9.DdEe ]+)"
unit = r"\(([^)]+)\)"
t = "[X] L=XU R=XU p=X e=X n=X"
m = re.compile(re.escape(t).replace("X", number).replace("U", unit))
于 2011-04-14T20:16:36.493 に答える
2

これは私には多かれ少なかれpythonicに見えます:

line = "[ 0 ] L= 9 (D) R= 14 (D) p= 0.0347222 e= 10 n= 34"

parts = (None, int, None,
         None, int, str,
         None, int, str,
         None, float,
         None, int,
         None, int)

[I,L,Ls,R,Rs,p,e,n] = [f(x) for f, x in zip(parts, line.split()) if f is not None]

print [I,L,Ls,R,Rs,p,e,n]
于 2011-04-14T20:25:09.467 に答える
1

Pythonには、Pythonのreページに記載されているscanfに相当するものがありません。

Pythonには現在、scanf()に相当するものはありません。正規表現は、scanf()形式の文字列よりも一般的に強力ですが、より冗長です。次の表は、scanf()形式のトークンと正規表現の間のほぼ同等のマッピングを示しています。

ただし、そのページのマッピングを使用して、独自のscanfのようなモジュールを作成することもできます。

于 2011-04-14T20:00:43.037 に答える
1

パイパーシングは、読み取り不能で壊れやすい正規表現プロセッサからのフォールバックです。以下のパーサーの例では、指定された形式に加えて、さまざまな余分な空白、および代入式の任意の順序を処理します。正規表現で名前付きグループを使用したのと同じように、pyparsingは結果名をサポートしているため、dictまたは属性構文(data ['Lint']またはdata.Lint)を使用して解析されたデータにアクセスできます。

from pyparsing import Suppress, Word, nums, oneOf, Regex, ZeroOrMore, Optional

# define basic punctuation
EQ,LPAR,RPAR,LBRACK,RBRACK = map(Suppress,"=()[]")

# numeric values
integer = Word(nums).setParseAction(lambda t : int(t[0]))
real = Regex(r"[+-]?\d+\.\d*").setParseAction(lambda t : float(t[0]))

# id and assignment fields
idRef = LBRACK + integer("id") + RBRACK
typesep = LPAR + oneOf("D G") + RPAR
lExpr = 'L' + EQ + integer("Lint")
rExpr = 'R' + EQ + integer("Rint")
pExpr = 'p' + EQ + real("pFloat")
eExpr = 'e' + EQ + integer("Eint")
nExpr = 'n' + EQ + integer("Nint")

# accept assignments in any order, with or without leading (D) or (G)
assignment = lExpr | rExpr | pExpr | eExpr | nExpr
line = idRef + lExpr + ZeroOrMore(Optional(typesep) + assignment)


# test the parser
text = "[ 0 ] L= 9 (D) R= 14 (D) p= 0.0347222 e= 10 n= 34"
data = line.parseString(text)
print data.dump()


# prints
# [0, 'L', 9, 'D', 'R', 14, 'D', 'p', 0.034722200000000002, 'e', 10, 'n', 34]
# - Eint: 10
# - Lint: 9
# - Nint: 34
# - Rint: 14
# - id: 0
# - pFloat: 0.0347222

また、解析アクションは、解析時にstring->intまたはstring->float変換を実行するため、その後、値はすでに使用可能な形式になっています。(pyparsingの考え方は、これらの式を解析しているときに、数字で構成される単語(またはWord(nums))が安全にintに変換されることを知っているので、一致する文字列を取得して取得するのではなく、すぐに変換を実行してみませんか?文字列のシーケンスを再処理し、整数、浮動小数点数などの文字列を検出しようとしますか?)

于 2011-04-15T00:08:38.110 に答える