0

特定のパターンを 1 つの正規表現行でいくつかの文字列に一致させたい (可能であれば):

blah blah (1023 mega lbs) blah blah 1245 tons
blah 1023 kilo tons blah blah 1034 metric tons
blah 1023 feet 345 blah
$100 is a lot of money

数字 (たとえば、行の最初の出現) 1023 とその単位 (ポンド、トン、フィート) を一致させ、別の単語の後に続く可能性があり、これを別の文字列として保存したいと考えています。ただし、$100 には注意する必要があります。これは、私が関心を持っている測定単位ではなく、その行の最初のシーケンスに続く可能性のある数字でもあるためです。

if statements私の現在のアプローチには、たとえば最初の行 (機能していない) など、多くのネストがあります:\d*\s(.*)\s\w+これを行うより良い方法はありますか?

4

2 に答える 2

3
import re
with open("input") as f:
    for line in f:
        mo=re.match(r'[^\d]*(\d+).*?(tons|feet|lbs)', line)
        if mo: print mo.group(1), mo.group(2)

出力

1023 lbs
1023 tons
1023 feet

また、 のような行がある場合は、次のよう$100 money is too much for 100 lbsに使用できます。

import re
with open("input") as f:
    for line in f:
        mo=re.match(r'.*?(?<![$\d])(\d+).*?(tons|feet|lbs)', line)
        if mo: print mo.group(1), mo.group(2)

そして、キロ、メガのものを一致させるために:

import re
with open("input") as f:
    for line in f:
        mo=re.match(r'.*?(\d+).*?(mega|kilo|metric|) (tons|feet|lbs)', line)
        if mo: print mo.group(1), mo.group(2), mo.group(3)

出力

1023 mega lbs
1023 kilo tons
1023  feet
100  lbs

これらの単位と修飾子をリストに保存し、それらを結合して|その場で正規表現を作成することができます。

可能なすべてのユニット修飾子に一致する例:

import re
with open("input") as f:
    for line in f:
        mo=re.match(r'[^\d]*(\d+).*?(\S*)\s*(tons|feet|lbs)', line)
        if mo: print "'{}' '{}' '{}'".format(mo.group(1), mo.group(2), 
                       mo.group(3))

出力

'1023' 'mega' 'lbs'
'1023' 'kilo' 'tons'
'1023' '' 'feet'
于 2013-05-28T22:12:28.897 に答える
0

http://regexpal.com/http://rubular.com/などの正規表現テスターを使用することをお勧めします。

(.*)真ん中が貪欲に一致し、意図した以上にキャプチャしてしまうため、問題があります. ここを参照してください。

<number> <scale> <unit>私のソリューションは、行ごとの最初の出現だけでなく、すべてのインスタンスに一致する必要があることに注意してください。後世のためにここに残します。

(?:[^0-9$]|^)(\d+)\s(\w+)\s(\w+)

これが実際のリンクです。

(?:[^0-9$]|^)は、一致が行の先頭から始まるか、その前に数字でもドル記号でもない何かがあることを示しています (それ?:をキャプチャしたくないことを意味します)。\d+次に、数字とそれに続く 2 つの単語を一致させます\w+\w+perreal's answer のように、 s をよりわかりやすい一致に置き換えることができます。

于 2013-05-28T22:47:58.873 に答える