Pythonでの文字列処理について。

20081110000001.543210 >> Host-1 192.168.0.1:12345
という文字列が与えられたときに、
['20081110000001', '543210', 'Host-1', '192.168.0.1', '12345']
というリストを得たいと考えています。
これまでは、

import re

line = '20081110000001.543210 >> Host-1 192.168.0.1:12345'
s = re.sub('(^\d+)\.(\d+) >> ([0-9A-z_-]+) (\d+\.\d+\.\d+\.\d+):(\d+)', '\g<1>,\g<2>,\g<3>,\g<4>,\g<5>', line)
lst = s.split(',')

のように、文字列lineから、いったん【,】で区切った文字列sを作って、それをsplitしてリストlstを得ていたのですが、いちいちsをつくるあたりが冗長な気がしています。
つまり、上記のコードで、re.sub()の第2引数で\g<x>を使って後方参照している文字列を、リストで取得したい、ということです。

このような書き方以外にうまい方法はないでしょうか。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2008/11/13 12:59:57
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:znz No.2

回答回数193ベストアンサー獲得回数25

ポイント50pt

リストではなくタプルになってしまいますが、MatchObjectのgroupsを使えばいいのではないでしょうか。

リストじゃないとダメならlistと組み合わせで。

import re
line = '20081110000001.543210 >> Host-1 192.168.0.1:12345'
m = re.match('(^\d+)\.(\d+) >> ([0-9A-z_-]+) (\d+\.\d+\.\d+\.\d+):(\d+)', line)
m.groups() #=> ('20081110000001', '543210', 'Host-1', '192.168.0.1', '12345')
list(m.groups()) #=> ['20081110000001', '543210', 'Host-1', '192.168.0.1', '12345']
id:S0R5

なるほど、そういうのがあったんですね。まさに求めていたものです。

助かりました。ありがとうございます。

2008/11/11 12:39:37

その他の回答1件)

id:karaki No.1

回答回数17ベストアンサー獲得回数6

ポイント30pt

フォーマットが以下の形で決まっているなら、replaceで対処できると思います。

s = "yyyymmddhhmiss.xxxxxx >> AAAA-X BBB.CCC.DDD.EEE:FFFF"
lst = [s[:14]]+s[15:].replace(" >> ",":").replace(" ",":").split(":")
>>> s="20081110000001.543210 >> Host-1 192.168.0.1:12345"
>>> [s[:14]]+s[15:].replace(" >> ",":").replace(" ",":").split(":")
['20081110000001', '543210', 'Host-1', '192.168.0.1', '12345']

書き方は他にも考えられると思いますが、このやり方が簡単ではないかと思います。


URLはダミーです。

http://www.python.org/

id:S0R5

replaceでデリミタを1種類にしてsplitするという方法ですか。たしかにこのフォーマットに決まってれば使えますね。ありがとうございます。

質問の書きかたが悪かったんですが、できれば、このフォーマットに限らず、任意のフォーマットで、今回書いたような、re.sub()の第2引数で\g<x>を使って後方参照している文字列をリストにする、汎用的な方法がないものかなと考えましたが、どうでしょうか。つまり、

line = 'abcdefghijklmnopqrstuvwxyz0123456789'
s = re.sub('(^abc).{3}(.{5}).+', '\g<1>,\g<2>', line)
lst = s.split(',')

で、

['abc', 'ghijk']

を得るといった場合にも使えるものを想定しています。

2008/11/10 22:54:37
id:znz No.2

回答回数193ベストアンサー獲得回数25ここでベストアンサー

ポイント50pt

リストではなくタプルになってしまいますが、MatchObjectのgroupsを使えばいいのではないでしょうか。

リストじゃないとダメならlistと組み合わせで。

import re
line = '20081110000001.543210 >> Host-1 192.168.0.1:12345'
m = re.match('(^\d+)\.(\d+) >> ([0-9A-z_-]+) (\d+\.\d+\.\d+\.\d+):(\d+)', line)
m.groups() #=> ('20081110000001', '543210', 'Host-1', '192.168.0.1', '12345')
list(m.groups()) #=> ['20081110000001', '543210', 'Host-1', '192.168.0.1', '12345']
id:S0R5

なるほど、そういうのがあったんですね。まさに求めていたものです。

助かりました。ありがとうございます。

2008/11/11 12:39:37

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません