2016-06-24 10 views
1

this SO postなど、私は多くの検索を行いました。Python Regexは、小数点以下のパターンとそれに続く別のパターンの一致に一致します。

巨大な文字列を使用して、10進数のパターンの後に英数字の単語の前に表示される4桁のグループをキャプチャしようとしています。

他の4桁の番号グループには、それらの前に単語または他の番号パターンがあるため、修飾されません。

EDIT:私の文字列は複数行ではなく、視覚的にわかりやすくするためにここに示してあります。例えば

>> my_string = """BEAVER COUNTY 001 0000 
1010 BEAVER 
2010 BEAVER COUNTY SCH DIST 
0.008504 
...(more decimals) 
0.008508 
4010 COUNTY SPECIAL SERVICE DIST NO.1 <---capture this 4010 
4040 BEAVER COUNTY 
8005 GREENVILLE SOLAR 
0.004258 
0.008348 
...(more decimals) 
0.008238 
4060 SPECIAL SERVICE DISTRICT NO 7 <---capture this 4060 
""" 

理想的なre.findallを返す必要があります:事前に

re.findall(r'(?=(\d\.\d{6}\s+)(\s+\d{4}\s))', my_string) 
# also tried   
re.findall("(\s+\d{4}\s+)(?:(?!^\d+\.\d+)[\s\S])*", my_string) 
# which gets me a little closer but I'm still not getting what I need. 

ありがとう:ここ

['4010','4060'] 

が欠けている、私が試した模様です!

+0

試し[ '(?M)^ \ D + \ \ D + [^ \ Sの\ rをする\ n] \ B' * [\ Rを\ n] +(\ dの{4})](HTTPS :\ regex101.com/r/gT6sS0/1) –

+0

're.findall(r '\ d \。\ d {6} \ s +(\ d {4})\ b'、my_string)'はどうですか? – WKPlus

+0

@WKPlus文字列が複数行でないときにあなたのメソッドが私のために働いた - ニース! – cheevahagadog

答えて

0

SINGLE LINEのSTRINGアプローチ:

はちょうど 4スタンドアロン桁の前にフロート番号と一致する:

r'\d+\.\d+\s+(\d{4})\b' 

this regex demo

Python demoを参照してください:

import re 
p = re.compile(r'\d+\.\d+\s+(\d{4})\b') 
s = "BEAVER COUNTY 001 0000 1010 BEAVER 2010 BEAVER COUNTY SCH DIST 0.008504 0.008508 4010 COUNTY SPECIAL SERVICE DIST NO.1 4040 BEAVER COUNTY 8005 GREENVILLE SOLAR 0.004258 0.008348 0.008238 4060 SPECIAL SERVICE DISTRICT NO 7" 
print(p.findall(s)) 
# => ['4010', '4060'] 

ORIGINAL ANSWER:複数行STRING

あなたが前の行にfloat値をチェックし、次の行に、スタンドアロンの4桁の数字をキャプチャします正規表現を使用することがあります。

re.compile(r'^\d+\.\d+ *[\r\n]+(\d{4})\b', re.M) 

regex demo here

を参照してください。

パターン説明

  • ^ - ラインの開始(として1+数字、.そして再び1桁以上
  • * - - ゼロ以上のスペース(水平空白に一致のみに[^\S\r\n]置き換える)
  • [\r\n]+から1以上LFまたはCR)は
  • \d+\.\d+使用されますシンボル((?:\r?\n|\r)に置き換え、1つの改行に制限のみに)
  • (\d{4})\bからre.findallマッチング4桁によって返されるグループ1は、ワード境界(非数字、非文字、非_)を用いました。

Python demo

import re 
p = re.compile(r'^\d+\.\d+ *[\r\n]+(\d{4})\b', re.MULTILINE) 
s = "BEAVER COUNTY 001 0000 \n1010 BEAVER \n2010 BEAVER COUNTY SCH DIST \n0.008504 \n...(more decimals)\n0.008508 \n4010 COUNTY SPECIAL SERVICE DIST NO.1 <---capture this 4010\n4040 BEAVER COUNTY \n8005 GREENVILLE SOLAR\n0.004258 \n0.008348 \n...(more decimals)\n0.008238 \n4060 SPECIAL SERVICE DISTRICT NO 7 <---capture this 4060" 
print(p.findall(s)) # => ['4010', '4060'] 
+0

これは素晴らしいことです!オリジナルの記事では、便宜のために複数行の文字列を作ったとは言いませんでした。それが複数行でないならば、それは大きく変わるのですか?私はそれを示すためにOPを編集します。 – cheevahagadog

+0

あなたは行単位で読むことを意味していますか? –

+0

これは、まだ行がなくても、巨大な進行中の文字列です。私はこの正規表現を使って 're.split'を行う場所を作ろうとしています。 – cheevahagadog

0

これがお手伝いします:

"((\d+\.\d+)\s+)+(\d+)\s?(?=\w+)"gm 

使用グループ3つの手段\ 3

Demo And Explaination

0

このパターを試してみてください。

re.compile(r'(\d+[.]\d+)+\s+(?P<cap>\d{4})\s+\w+') 

少しコードを書いてチェックして動作します。

import re 

p=re.compile(r'(\d+[.]\d+)+\s+(?P<cap>\d{4})\s+\w+') 

my_string = """BEAVER COUNTY 001 0000 
1010 BEAVER 
2010 BEAVER COUNTY SCH DIST 
0.008504 
...(more decimals) 
0.008508 
4010 COUNTY SPECIAL SERVICE DIST NO.1 <---capture this 4010 
4040 BEAVER COUNTY 
8005 GREENVILLE SOLAR 
0.004258 
0.008348 
...(more decimals) 
0.008238 
4060 SPECIAL SERVICE DISTRICT NO 7 <---capture this 4060 
""" 

s=my_string.replace("\n", " ") 

match=p.finditer(s) 

for m in match: 
    print m.group('cap') 
関連する問題