1

次の正規表現を適用しようとすると、問題に直面しています。

(1234).*?(abcd)?

以下の文字列に:

1234567abcd

私の期待は、上記が2つの一致を生成するはずです:

  1. 1234
  2. あいうえお

ただし、これは機能しません。「まあ、末尾の?文字を削除するだけですか?」と提案するかもしれません。-- しかし、私はこの 2 番目のパターンをオプションにしたいと考えています。

これはどのように行われますか?

繰り返します:

(1234).*?(abcd)

...目的の結果が得られますが、検索文字列に常に含まれるとは限りませんabcd

疑問に思っている人のために説明すると、これは全体像の問題の単純化された例です。必要に応じて説明します。

====

この問題にはさらに説明が必要だと思います。これは、Ruby で私がやろうとしていることのより完全な例です。

私のログファイルから次の 2 つの「ドキュメンテーション」行があるとします。

Aug 28 00:00:05 app-system-1 app-prod[7660]: Completed 200 OK in 150ms (Views: 24.6ms | ActiveRecord: 66.1ms)
Aug 28 00:05:06 app-system-1 app-prod[10639]: Completed 302 Found in 81ms (ActiveRecord: 74.6ms)

次のようにRubyで正規表現をコンパイルしようとしました:

d=Regexp.new('(?<timestamp>\w{1,3}\s\d{1,2}\s\d\d:\d\d:\d\d).*(?<in>in [0-9]*).*(?<views>Views: [0-9]*).*(?<activerecord>ActiveRecord: [0-9]*)')

明らかに、「ビュー」テキストが含まれる場合もありますが、他の行には存在しません。

私は次のようなことができるようにしたい:

v=d.match(line)
if !v.nil?
    puts v[:timestamp]+ " " + v[:in] + " " + v[:views] + " " + v[:activerecord]

これは明らかに不完全な例ですが、これで明確になることを願っています。

4

5 に答える 5

2

少なくとも明確には、あなたが望むものを指定していませんでしたが、次のものが欲しいと思います:

  • ...1234567abcd...入力として与えられた場合1234567abcd、一致する必要があり1234abcdキャプチャする必要があります。
  • ...1234567abce...入力として与えられた場合1234、一致する1234必要があり、キャプチャする必要があります。

その場合は、次を使用できます。

/(1234)(?:.*?(abcd))?/s

貪欲修飾子を使うのは嫌いです。特定のシーケンスの一致を回避するために使用されますが、一致しないという保証はありません。代わりに次を使用します。

/
   (1234)
   (?:
      (?:(?!abcd).)*    # Safer than .*?
      (abcd)
   )?
/sx
于 2012-08-31T02:20:04.543 に答える
1

正規表現のアンカーは次のように機能します。

/(1234).*?(abcd)?$/
于 2012-08-31T02:18:15.447 に答える
1

池上に似ていますが、より単純だと思います:

/(1234)(?:(?!abcd).)*(abcd)?/
于 2012-08-31T03:30:37.367 に答える
0

(a|)は次のものとほぼ同等であるため、(a)?以下を使用できます。

(1234).*?(abcd|)

正規表現エンジンに最初の検査を強制するにはabcd。オプションのルール with のデフォルトは、?それが存在しないと仮定することです (これは と同等です(|abcd))。このデフォルトの動作は、正規表現が (より速く) 終了するようにするために重要です。

于 2012-08-31T02:14:12.497 に答える
0

あなたは本当にそれを段階的に行うべきです。

if (my ($ts, $dur, $breakdown) = /
   ^
   (\w{3}[ ]\d{1,2}[ ]\d\d:\d\d:\d\d)
   .*?
   in[ ]([0-9]*)ms
   .*?
   \( ([^()]*) \)
/xs) {
   my %breakdown = map /^([^:]+): (.*)ms/, split /\s*\|\s*/, $breakdown;
   say join ', ',
      $ts,
      $dur,
      $breakdown{Views} // '--',
      $breakdown{ActiveRecord} // '--';
}
于 2012-08-31T04:22:29.227 に答える