質問
J0000000: Transaction A0001401 started on 8/22/2008 9:49:29 AM
J0000010: Project name: E:\foo.pf
J0000011: Job name: MBiek Direct Mail Test
J0000020: Document 1 - Completed successfully
この巨大な醜い文字列があり、正規表現を使用してそこから部分を抽出しようとしています。
この場合、「プロジェクト名」以降、「J0000011:」の部分までをすべて取得したいと思います(11は毎回異なる数字になります)。
これが私が遊んでいる正規表現です
Project name:\s+(.*)\s+J[0-9]{7}:
問題は、それが到達するまで止まらないことです。 J0000020: 最後に。
正規表現を最初の出現箇所で停止させるにはどうすればよいですか? J[0-9]{7}?
解決
作る .*
' を追加することで貪欲にならないようにする?
' その後:
Project name:\s+(.*?)\s+J[0-9]{7}:
他のヒント
ここで非貪欲量指定子を使用することは、おそらく最良の解決策です。これは、貪欲な代替方法よりも効率的であるためです。貪欲な一致は通常、可能な限り (ここではテキストの終わりまで) まで行ってから、文字ごとに遡って、その後に来る部分との一致を試みます。
ただし、代わりに負の文字クラスを使用することを検討してください。
Project name:\s+(\S*)\s+J[0-9]{7}:
\S
は「空白以外のすべて」を意味し、これがまさにあなたが望むものです。
良い、 ".*"
貪欲なセレクターです。を使用して非貪欲にします ".*?"
後者の構造を使用する場合、正規表現エンジンは各ステップでテキストを一致させます。 "."
の後に来るものと一致しようとします ".*?"
. 。これは、たとえば、次の後に何も来ない場合、 ".*?"
, 、その場合は何も一致しません。
私が使用したものはこちらです。 s
元の文字列が含まれています。このコードは .NET 固有ですが、ほとんどの正規表現には同様のものがあります。
string m = Regex.Match(s, @"Project name: (?<name>.*?) J\d+").Groups["name"].Value;
また、「Expresso」を使用して正規表現を試してみることをお勧めします。これは、正規表現の編集とテストに最適な (無料の) ユーティリティです。
その利点の 1 つは、その UI が、正規表現に慣れていない人にとって馴染みのない多くの正規表現機能を、新しい概念を簡単に学習できる形で公開していることです。
たとえば、UI を使用して正規表現を構築し、「*」を選択する場合、「可能な限り少ない」チェックボックスをオンにして、結果の正規表現を確認したり、その動作をテストしたりすることができます。以前は欲張らない表現。
サイトからダウンロードできます:http://www.ultrapico.com/Expresso.htm
(プロジェクト名:\s+[A-Z]:(?:\\w+)+.[a-zA-Z]+\s+J[0-9]{7})(?=:)
これはうまくいきます。
(?:\\w+)+.[a-zA-Z]+ を追加すると、.* の代わりに制限が厳しくなります。