3

2 つの文字列間でテキストを一致させたいのですが、最初の文字列には厳密な境界条件があります。

サンプル入力:

start
From: h
From:b
 xyz
Subject: 
end

と の間で一致させる必要がFrom:ありSubject:ます。

(From:.*).*(Subject:)dotall で使用すると、生成されます

From: h
From:b
 xyz
Subject:

しかし、私はただ必要です

From:b
 xyz
Subject:

開始文字列には厳密な境界条件があるためです。これが必要なのは、開始文字列がドキュメントのどこにでもある可能性があり、上記の正規表現は数行ではなく大きなテキストに一致するためです。

%%%%%%%%%%%% 問題の再定義 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

From:<any text>
To:<any text>
Subject:<any text>

キャッチは次のとおりです。3つのコンポーネントはすべて1行に入れることも、1つの改行で区切ることも、2つの改行で区切ることもできます... を含む可能性のある目的の一致の前後にテキストがありますFrom:<any text>。そのため、厳密が必要です境界。

4

4 に答える 4

2

これを試してください:

String input = "start From: h From:b xyz Subject: end";
Matcher matcher = Pattern.compile("(?<=^((?!From:).)*(From: [A-Za-z0-9] ))(.+?)(Subject:)").matcher(input);
if (matcher.find())
{
    System.out.println(matcher.group());
}

出力: From:b xyz Subject:.


正規表現の説明 ( (?<=^((?!From:).)*(From: [A-Za-z0-9] ))(.+?)(Subject:)):

  • (?<=後ろを見始める
  • ^文字列の開始
  • ((?!From:).)先を見ても「From:」が見えない場合は、任意の文字に一致します
  • *前のステートメントに 0 回以上一致する
  • (From: [A-Za-z0-9] ))最初の「From:」とその内容に一致します
  • )後ろを見るのをやめる
  • (.+?)探している文字列に一致します
  • (Subject:)件名フィールドに一致します
于 2013-04-28T00:46:46.387 に答える
0

.*DOTALL モードで使用する代わりに行がFrom:.

"(?m)^From:.*[\r\n]+(?:(?!From:).*[\r\n]+)*Subject:.*$"

それが最低限の実装です。テキストの構造によっては、一致が多すぎたり遅すぎたりする可能性があります (特に一致が不可能な場合)。より堅牢なバージョンは次のとおりです。

"(?m)^(?>From:.*[\r\n]+)(?>(?!From:|Subject:).*[\r\n]+)*+Subject:.*$"
于 2013-04-28T03:48:59.273 に答える