2

私は正規表現の初心者で、助けが必要です。テーブルを表すテキストがあります。私はそれが7つの列で構成されることを知っています:

| int | int mixed with -. | unicode string with everything | float | float | int | float |

問題は、floatが数千のスペースを使用して表現されることです(1234,43 => 1 234,43)。さらに、文字列はスペースを含み、数字で終わることができます。私はこのようなことを試しました(改行文字のストライプごとに):

regex = re.compile(r"(\d+) ([\d.-]+) (.*) ([\d+ ]?\d+,\d+) ([\d+ ]?\d+,\d+) (\d+) ([\d+ ]?\d+,\d+)$", re.UNICODE)
w = regex.findall(line)

残念ながら、すべての場合に機能するとは限りません。いくつかのテストデータ:

49 602 DSKOD SMCX 262,59 1 131,30 1 1 131,30
49 602 DSKOD SMCX 3 5 262,59 1 131,30 1 1 131,30
50 61-201 łóćźż 1 2 669,50 334,75 1 334,75
51 1-214 AÓŻĆÓDS" 70,35 350,18 3 105,53

私が得ているように、数千のケースは問題があります:

[]
[]
[(u'50', u'61-201', u'\u0142\xf3\u0107\u017a\u017c 1 2', u'669,50', u'334,75', u'1', u'334,75')]
[(u'51', u'1-214', u'A\xd3\u017b\u0106\xd3DS"', u'70,35', u'350,18', u'3', u'105,53')]

3番目の例2では、文字列の最後を次の列に配置します。Python 2.7で、これを適切に一致させる方法についていくつかの手がかりがあることを知っていますか?後でこのUnicodeと戦います。

4

2 に答える 2

2

問題は[\d+ ]?です。これは、0桁または1桁のプラス、スペースに一致します。その他の問題は、列の区切り文字とフィールド内で引用符を使用せずにスペースを使用することですが、これはデータに対して機能します。また、余分な文字が含まれている2番目の列.と、スペース以外の文字のみを取得するように3番目の列を変更しました。

#!python3
# coding: utf-8
import re

data = '''\
49 602 DSKOD SMCX 262,59 1 131,30 1 1 131,30
49 602 DSKOD SMCX 3 5 262,59 1 131,30 1 1 131,30
50 61-201 łóćźż 1 2 669,50 334,75 1 334,75
50 61-201 łóćźż 1 669,50 334,75 1 334,75
51 1-214 AÓŻĆÓDS" 70,35 350,18 3 105,53
'''.splitlines()

regex = re.compile(r"(\d+) ([\d-]+) (.*?) ((?:\d{1,3})?(?:\ \d{3})*,\d{2}) ((?:\d{1,3})?(?:\ \d{3})*,\d{2}) (\d+) ((?:\d{1,3})?(?:\ \d{3})*,\d{2})", re.UNICODE)
for line in data:
    print(regex.match(line).groups())

出力:

('49', '602', 'DSKOD SMCX', '262,59', '1 131,30', '1', '1 131,30')
('49', '602', 'DSKOD SMCX 3', '5 262,59', '1 131,30', '1', '1 131,30')
('50', '61-201', 'łóćźż 1', '2 669,50', '334,75', '1', '334,75')
('50', '61-201', 'łóćźż', '1 669,50', '334,75', '1', '334,75')
('51', '1-214', 'AÓŻĆÓDS"', '70,35', '350,18', '3', '105,53')
于 2013-03-24T17:19:19.237 に答える
1

これを次のように分割します。

r = re.compile(r"(\d+) 
                 ([\d.-]+) 
                 ([^ ]*) 
                 ((\d+ ?)+,\d+) 
                 ((\d+ ?)+,\d+) 
                 (\d+) 
                 ((\d+ ?)+,\d+)$", re.UNICODE)

変更はユニコード部分にあり、それほど貪欲にならず、スペースを避け、次にフロート部分にあります。フロートにコンマがないという問題があります。

最初の行:

In [21]: r.findall(l)
Out[21]: 
[('49',
  '602',
  'DSKODSMCX',
  '2 262,59',
  '262',
  '1 131,30',
  '131', #!
  '1',
  '1 131,30',
  '131')] #!

#でマークされた行 「\d\ d\d」パターンを繰り返すために使用したネストされたグループの結果である追加のキャプチャです。

別のサンプル:

In [23]: l2 = '49 602-1 DKSAJ 231 442 123,2 1 123 123,4 1 1 533 123,2'

In [24]: r.findall(l2)
Out[24]: 
[('49',
  '602-1',
  'DKSAJ',
  '231 442 123,2',
  '123',
  '1 123 123,4',
  '123',
  '1',
  '1 533 123,2',
  '123')]
于 2013-03-24T17:21:33.970 に答える