2016-08-16 2 views
1

私は文字列の2つのピースを持っています。任意の文字に一致する正規表現か、まったく一致しませんか?

line1 = [16/Aug/2016:06:13:25 -0400] "GET /file/ HTTP/1.1" 302 random stuff ignore 

line2 = [16/Aug/2016:06:13:25 -0400] "" 400 random stuff ignore 

私はこれらの2つの部分を取得しようとしています。

"GET /file/ HTTP/1.1" 302 
"" 400 

基本的に2つの間の任意の文字または ""の間には何もありません。これまで私はこれを試しました。

regex_example = re.search("\".+?\" [0-9]{3}", line1) 
print regex_example.group() 

これはline1で動作しますが、line2でエラーが発生します。これは '。'のためです任意の文字に一致しますが、文字が存在しない場合はエラーを返します。

2つの文字の間に一致する文字はありませんか?

+1

使用 'R ' "[^"] *」[0-9] {3}'' – anubhava

答えて

4

.+?の代わりに.*?を使用してください。

+が「1以上」を意味

*は、あなたがより効率的な正規表現をしたい場合は

Regex101 Demo

は、怠惰な数量詞の代わりに否定文字クラス[^"]を使用する「0以上」を意味します?。数字には生の文字列フラグr\dも使用する必要があります。あなたが使用することができます

r'"[^"]*" \d{3}' 
1

import re 

lines = ['[16/Aug/2016:06:13:25 -0400] "GET /file/ HTTP/1.1" 302 random stuff ignore', '[16/Aug/2016:06:13:25 -0400] "" 400 random stuff ignore'] 

rx = re.compile(r''' 
     "[^"]*" # ", followed by anything not a " and a " 
     \  # a space 
     \d+  # at least one digit 
     ''', re.VERBOSE) 

matches = [m.group(0) \ 
      for line in lines \ 
      for m in rx.finditer(line)] 

print(matches) 
# ['"GET /file/ HTTP/1.1" 302', '"" 400'] 


a demo on ideone.comを参照してください。

0

お試しください... '検索'の代わりに 'findall'を使用すると、出力の処理方法をより詳細に制御できます。

import re 

output = [] 

logs = '[16/Aug/2016:06:13:25 -0400] "GET /file/ HTTP/1.1" 302 random stuff ignore \ 
     [16/Aug/2016:06:13:25 -0400] "" 400 random stuff ignore' 

regex = r'"(.*?)"\s(\d{3})' 

value = re.findall(regex, logs) 
output.append(value) 

print(output) 
0

もっと簡単な答え。

import re 
    line1= '[16/Aug/2016:06:13:25 -0400] "GET /file/ HTTP/1.1" 302 random stuff ignore' 
    line2='[16/Aug/2016:06:13:25 -0400] "" 400 random stuff ignore' 

    x=re.search('\](.+)random',line1).group(1) 

    y= re.search('\](.+)random', line2).group(1) 

    print(x + "\n"+y) 

あなたは次のような出力になります

 "GET /file/ HTTP/1.1" 302 
    "" 400 
関連する問題