2015-12-07 6 views
10

で始まらない行I持ってパイソン:#

#コメント
#コメント
ないコメント

#コメント
#コメント
ないようなものが含まれているファイルコメント

私はラインaでファイルの行を読みしようとしています#で始まらない行だけをキャプチャします。私のコード/正規表現で何が間違っていますか?

import re 

def read_file(): 
    pattern = re.compile("^(?<!#).*") 

    with open('list') as f: 
     for line in f: 
      print pattern.findall(line) 

オリジナルコードでは、期待されるものではなくすべてがキャプチャされます。

+3

lookbehindは、*現在の位置の前の何かをチェックし、先読みは現在の位置の後ろにあるものをチェックします。正規表現が本当に必要な場合は先読みを使用してください。しかし、あなたは本当に正規表現を必要としません。 –

+0

あなたは 'regex'としてやる必要がありますか?...あなただけの' buitl-in'方法でそれを行うことができます... regex' –

答えて

12

代替とシンプルなアプローチは、あなたが#文字が含まれていない読んで、各行の最初のcharが場合にのみチェックすることです:

def read_file(): 

    with open('list') as f: 
     for line in f: 
      if not line.lstrip().startswith('#'): 
       print line 
+1

'のお手間を節約できます。しかし、私はしていませんなぜOPは*を求めていると思います'^(?<!#)。*この場合は'作業*、*ない*これを実行する方法について説明します。 –

+0

はい。私はこれが動作すると思います。しかし、あなたは正規表現が機能しない理由を知っていますか? – Mico

+3

はたぶん。STARTSWITH(「#」) '場合に行が' '#の前に空白を持つことができる)、それ(' line.lstripを使用して、もう少し防弾します。 @Mico:あなたは*の戻り読み*アサーションの代わりに、*先取り*アサーションを使用していました。 Lookbehindは改行文字を行の開始前に見ます。改行文字は行の開始後の '# '文字ではありません。 –

10

Iron Fistあなたはおそらくこれを行うべき道を示しています。

^[^#].* 

説明: - 行の先頭に一致する

  • ^あなたはとにかくあなたの正規表現で間違っていたかを知りたい場合は、このされている必要があります。
  • [^#]から#ではない何かを一致させます。例えば、[^ABC123]は、A、B、C、1,2,3のいずれにも該当しない文字と一致します。Don 'トンライン/文字列の先頭には、ここであなたを混乱させる示し^てみましょうこれら二つの^年代は全く関係のない、
  • .* - 何か他のもののゼロ個以上に一致する

EDIT:。。。

理由:^(?<!#).*# commentnot a commentを区別しません(?<!#)チェックテキスト前に現在の位置ということです。エンジンは文字列の開始後の最初のシンボルの前に#を探し、文字列の先頭の前には#がないので、いずれの行も.*サブパターンと一致します。最初のシンボルが#かどうかを実際に確認するには、^#.*正規表現を使用する必要があります。または、先頭に空白がある場合は、^\s*#。それが最初に確認されますので、

+0

それはなぜ機能しないのですか? –

+0

@KevinGuan:これを説明するためのアップデートを追加しました。 –

+2

@MikeCovington:間違った説明です。 –

1

は、この大文字でmatch機能を使用してください。

したがって、式は\s*[^#]になります。正気のために、私は\sを使用して空白を渡します。BE-ます

OPのコード

def read_file(): 
    pattern = re.compile("\s*[^#]") 
    with open(r"C:\test.txt") as f: 
     for line in f: 
      if pattern.match(line): 
        print line 
read_file() 

編集 -

あなたはそれがすべて除く改行文字を意味.を使用する場合はOPのパターンが

をworking-されていない理由ビット説明。あなたが^(?<!#).*を書くとき、最終的には(改行バリアントを除く)任意の文字列になりany文字で始まるビフォー#はしていない(ラインが、それは#気をそれ!含みブレイクを除く)だから、any文字を意味します。

LIVE DEMO

ソリューション参照してください:

てみnegationよう^(?<!#)[^#]

4

ため:

(?!#)先読み - 再と一致することは不可能であることをアサートgex以下
(?<!#)負の値ルックバックヒント - 正規表現#と一致するとは限りません。それは、それだけでその背後にある#が一致することを意味しregex101

から
。つまり、私が意味することは:

>>> re.search('foo(?!bar)', 'foobar') 
>>> re.search('foo(?<!bar)', 'foobar') # doesn't work 
<_sre.SRE_Match object; span=(0, 3), match='foo'> 


>>> re.search('(?<!bar)foo', 'barfoo') 
>>> re.search('(?!bar)foo', 'barfoo') # doesn't work 
<_sre.SRE_Match object; span=(3, 6), match='foo'> 

間違ったトークンを使用したためです。だから、答えは非常に簡単です:

使用(?!bar)あなたはbar後にいくつかの文字列を使用しない場合は
の場合は、の前にbarの前に、(?<!bar)を使用してください。

+0

なぜ**で始まる答えは**ですか? – SIslam

+2

@SIslam:OPが尋ねられたので*私のコード/正規表現に何が間違っていますか?*だから** ... –

+0

@KevinGuanありがとう – Mico