0

正規表現で、任意の数の任意の文字 (例: (.|\n)*) を、後に続く可能性のある他の一致を消費せずに一致させるにはどうすればよいですか? その質問が明確でない場合、これが私の状況です。

テキスト ファイルには、ヘッダーを含む多数のメールがまとめて貼り付けられています。

編集:以下のよりクリーンなバージョンでは、改行の先頭に各ヘッダーがあります。それは、私の実際のデータに当てはまる場合とそうでない場合があります。各ヘッダー コンポーネント ('From: xxx' など) の前に何かを付けても、何も付けなくてもかまいません。場合によっては、多くの電子メールとヘッダーがすべて 1 行に収まり、他の面倒な作業が続くことがあります。その上、'From:' が含まれていることを認識する必要がある他の電子メール ヘッダーがあります。したがって、このヘッダー スタイル全体を認識する必要があります。

私の編集の前に与えられた以下のいくつかの回答は、私が当てにできない ^ やタブ区切りなどに依存しています。少し変更すればうまくいくように見えますが、私は (明らかに) 正規表現が得意ではなく、自分で調整することはできませんでした。以前にこれを省略して申し訳ありませんが、いくつかの回答者がそれをつかむためだけに...正規表現に関する私の経験不足の別の製品です。

これは醜いバージョンです - これは私が実際に一致させようとしている文字列です。抽出する 2 つのヘッダーとメッセージが含まれています。

emailsString = u"""From:\n     Lastname, Firstname\n     Sent:\n     Monday, June 24, 2013 1:48 PM\n     To:\n     Othername, Name\n     Subject:\n     RE: Center update\n    Message message message.\n    Such a lovely message\n    Take care,\n    Firstname Lastname, MS\n     Long signature\n     in this email\n   \n    E-mail:\n     email@email.com\n     Web\n     my blog\n     From:\n     Lastname, Firstname\n     Sent:\n     Monday, June 24, 2013 9:33 AM\n     To:\n     Othername, Name\n     Subject:\n     Center update\n     Importance:\n     High\n    Good Morning Name,\n    I hope this finds you doing well.\n    I wanted to inform you of some changes. The Center will be closing August 30\n     th\n     .  or September 1\n     st\n     .  I\u2019ve enjoyed my experience. """

これは、ヘッダーがどのように見えるかを示すためのよりクリーンなバージョンです

From: Lastname, Firstname
Sent: Monday, July 15th, 2011, 9:36 AM
To: Othername, Name
Subject: blah
Importance: High

Message message message
second line of message

second para of message

From: Lastname, Firstname
Sent: Thursday, July 18th, 2011, 10:45 AM
To: Othername, Name
Subject: blahblah

message

...

メッセージ自体とともにヘッダー内の情報を正規表現しようとしています。すべてのヘッダーを正常に照合できる正規表現がありますが、メッセージに苦労しています。問題は、メッセージに何でも (または何も) 含めることができることです。複数の改行などがある可能性があります。これをすべて取得したいのですが、それでもメールを分割したいと考えています。私の試み(ヘッダーの「重要」部分はオプションであることに注意してください):

for hit in re.finditer(r'[\s\n]*From:[\s\n]*(?P<from>.*)[\s\n]*Sent:[\s\n]*(?P<date>.*)[\s\n]*To:[\s\n]*(?P<to>.*)[\s\n]*Subject:[\s\n]*(?P<subject>.*)[\s\n]*(?:Importance:)?[\s\n]*.*[\s\n]*(?P<message>(.|\n)*)', allEmailsString):
    print "from: " + hit.group("from")
    print "to: " + hit.group("to")
    print "date: " + hit.group("date")
    print "subject: " + hit.group("subject")
    print "message: " + hit.group("message")

問題は、メッセージ グループがすべてを取得していることです。したがって、最初の電子メール ヘッダーの from/to/etc を正しく取得し、その電子メール メッセージを含むメッセージと、それに続くすべての電子メール ヘッダーおよびメッセージを確認します。「次の電子メール ヘッダー/正規表現の一致まで、または文字列の最後まで」すべてを取得する必要があります。

回避策は既にあります。メッセージ キャプチャ グループを削除して、ヘッダーのみを取得できます。次に、一致オブジェクトを繰り返し処理し、開始/終了に基づいて文字列をスライスします。たとえば、message1 は match1.end から match2.start までです。

だから、私は尋ねています...

  • 代わりに、正規表現でグループをキャプチャしてこれを行う方法はありますか?
  • より良い回避策はありますか?
4

3 に答える 3

0

これは見ていて辛いかもしれません。わかりやすくするために拡大しています。
Multi-Line モードと No-DotAll を使用します。

@mobabo - 最初のコメントの後にこれを編集してください。

キーワードを明確に説明する必要があります。あなたの声明は
I can't count on things like '^From' to work、前の正規表現を見ていないことを示して
おり、その部分はこの正規表現でも同じです。^[^\S\n]*From:と同じではありません^From


さらに、件名とメッセージ、または重要度とメッセージの間に明確な線引きがありません。「重要度」が電子メールの一部である場合、件名にはエンドポイントがあります。

私はあなたの汚れた電子メールときれいな電子メールを処理する正規表現を作成しました。下部には、
それを実行する Perl プログラムがあります。出力が含まれています。問題が解決するかどうかを確認してください
(以下を参照)。

残念ながら、これはあなたが望むことができる最高のものです。

がんばれ!
(注 - Python に再帰がある場合、この正規表現はこのサイズの 1/4 になります)

 # Compressed
 # -------------------
 #  ^[^\S\n]*From:\s*(?P<from>(?:(?!\s*^[^\S\n]*(?:From|Sent|To|Subject|Importance):)[\S\s])*)(?:\s*^[^\S\n]*Sent:\s*(?P<sent>(?:(?!\s*^[^\S\n]*(?:From|Sent|To|Subject|Importance):)[\S\s])*))?(?:\s*^[^\S\n]*To:\s*(?P<to>(?:(?!\s*^[^\S\n]*(?:From|Sent|To|Subject|Importance):)[\S\s])*))?(?:\s*^[^\S\n]*Subject:\s*(?P<subject>(?:(?!\s*^[^\S\n]*(?:(?:From|Sent|To|Subject|Importance)):)[\S\s])*)(?:\s*^[^\S\n]*Importance:\s*(?P<importance>(?:(?!\s*^[^\S\n]*(?:From|Sent|To|Subject|Importance):)[\S\s])*))?)?

 # Expanded
 # -------------------
 #

 ^ [^\S\n]* From: \s* 
 (?P<from>
      (?:
           (?!
                \s* ^ [^\S\n]* 
                (?: From | Sent | To | Subject | Importance )
                :
           )
           [\S\s] 
      )*
 )

 (?:
      \s* ^ [^\S\n]* Sent: \s* 
      (?P<sent>
           (?:
                (?!
                     \s* ^ [^\S\n]* 
                     (?: From | Sent | To | Subject | Importance )
                     :
                )
                [\S\s] 
           )*
      )
 )?

 (?:
      \s* ^ [^\S\n]* To: \s* 
      (?P<to>
           (?:
                (?!
                     \s* ^ [^\S\n]* 
                     (?: From | Sent | To | Subject | Importance )
                     :
                )
                [\S\s] 
           )*
      )
 )?

 (?:
      \s* ^ [^\S\n]* Subject: \s* 
      (?P<subject>
           (?:
                (?!
                     \s* ^ [^\S\n]* 
                     (?:
                          (?: From | Sent | To | Subject | Importance )
                     )
                     :
                )
                [\S\s] 
           )*
      )

      (?:
           \s* ^ [^\S\n]* Importance: \s* 
           (?P<importance>
                (?:
                     (?!
                          \s* ^ [^\S\n]* 
                          (?: From | Sent | To | Subject | Importance )
                          :
                     )
                     [\S\s] 
                )*
           )
      )?
 )?


 # // Output from Perl sample code (below)
 # //
 # // ======================
 # // From:
 # //         Lastname, Firstname
 # // Sent:
 # //         Monday, July 15th, 2011, 9:36 AM
 # // To:
 # //         Othername, Name
 # // Subject:
 # //         blah
 # // Importance/Message:
 # //         High
 # // 
 # // Message message message
 # // second line of message
 # // 
 # // second para of message
 # // 
 # // 
 # // ======================
 # // From:
 # //         Lastname, Firstname
 # // Sent:
 # //         Thursday, July 18th, 2011, 10:45 AM
 # // To:
 # //         Othername, Name
 # // Subject/Message:
 # //         blahblah
 # // 
 # // message
 # // 
 # // 
 # // ======================
 # // From:
 # //         Lastname, Firstname
 # // Sent:
 # //         Monday, June 24, 2013 1:48 PM
 # // To:
 # //         Othername, Name
 # // Subject/Message:
 # //         RE: Center update
 # //     Message message message.
 # //     Such a lovely message
 # //     Take care,
 # //     Firstname Lastname, MS
 # //      Long signature
 # //      in this email
 # // 
 # //     E-mail:
 # //      email@email.com
 # //      Web
 # //      my blog
 # // 
 # // 
 # // ======================
 # // From:
 # //         Lastname, Firstname
 # // Sent:
 # //         Monday, June 24, 2013 9:33 AM
 # // To:
 # //         Othername, Name
 # // Subject:
 # //         Center update
 # // Importance/Message:
 # //         High
 # //     Good Morning Name,
 # //     I hope this finds you doing well.
 # //     I wanted to inform you of some changes. The Center will be closing August 30
 # // 
 # //      th
 # //      .  or September 1
 # //      st
 # //      .  I've enjoyed my experience.
 # // 

 # ------------------------------------------------------------
 # # Perl sample code
 # use strict;
 # use warnings;
 # 
 # $/ = undef;
 # 
 # my $str = <DATA>;
 # 
 # 
 # 
 # while ( $str =~ /
 #     ^[^\S\n]*From:\s*(?P<from>(?:(?!\s*^[^\S\n]*(?:From|Sent|To|Subject|Importance):)[\S\s])*)(?:\s*^[^\S\n]*Sent:\s*(?P<sent>(?:(?!\s*^[^\S\n]*(?:From|Sent|To|Subject|Importance):)[\S\s])*))?(?:\s*^[^\S\n]*To:\s*(?P<to>(?:(?!\s*^[^\S\n]*(?:From|Sent|To|Subject|Importance):)[\S\s])*))?(?:\s*^[^\S\n]*Subject:\s*(?P<subject>(?:(?!\s*^[^\S\n]*(?:(?:From|Sent|To|Subject|Importance)):)[\S\s])*)(?:\s*^[^\S\n]*Importance:\s*(?P<importance>(?:(?!\s*^[^\S\n]*(?:From|Sent|To|Subject|Importance):)[\S\s])*))?)?
 # /xmg)
 # 
 # {
 #  print "\n\n======================\n";
 #  print "From: \n\t$+{from}\n";
 #  if (defined $+{sent})
 #  {
 #      print "Sent: \n\t$+{sent}\n";
 #  }
 #  if (defined $+{to})
 #  {
 #      print "To: \n\t$+{to}\n";
 #  }
 #  if (defined $+{importance})
 #  {
 #      print "Subject: \n\t$+{subject}\n";
 #      print "Importance/Message: \n\t$+{importance}\n";
 #  }
 #  elsif (defined $+{subject})
 #  {
 #      print "Subject/Message: \n\t$+{subject}\n";
 #  }
 # }
 # 
 # 
 # __DATA__
 # 
 # From: Lastname, Firstname
 # Sent: Monday, July 15th, 2011, 9:36 AM
 # To: Othername, Name
 # Subject: blah
 # Importance: High
 # 
 # Message message message
 # second line of message
 # 
 # second para of message
 # 
 # From: Lastname, Firstname
 # Sent: Thursday, July 18th, 2011, 10:45 AM
 # To: Othername, Name
 # Subject: blahblah
 # 
 # message
 # 
 # 
 # 
 # 
 # 
 # From:
 #      Lastname, Firstname
 #      Sent:
 #      Monday, June 24, 2013 1:48 PM
 #      To:
 #      Othername, Name
 #      Subject:
 #      RE: Center update
 #     Message message message.
 #     Such a lovely message
 #     Take care,
 #     Firstname Lastname, MS
 #      Long signature
 #      in this email
 #    
 #     E-mail:
 #      email@email.com
 #      Web
 #      my blog
 #      From:
 #      Lastname, Firstname
 #      Sent:
 #      Monday, June 24, 2013 9:33 AM
 #      To:
 #      Othername, Name
 #      Subject:
 #      Center update
 #      Importance:
 #      High
 #     Good Morning Name,
 #     I hope this finds you doing well.
 #     I wanted to inform you of some changes. The Center will be closing August 30
 #      th
 #      .  or September 1
 #      st
 #      .  I've enjoyed my experience.
 # 
 # 
于 2013-10-29T01:02:34.773 に答える