1

テキスト行の末尾にあるオプションのタグに一致させたい。

入力テキストの例:

The quick brown fox jumps over the lazy dog {tag}

中括弧の部分を一致させ、それへの後方参照を作成したいと思います。

私の正規表現は次のようになります。

^.*(\{\w+\})?

(やや簡略化されていますが、タグの前の部分も一致しています):

行は (タグの有無にかかわらず) 一致しますが、タグへの後方参照は作成されません。

「?」を削除すると 文字なので、正規表現は次のとおりです。

^.*(\{\w+\})

タグへの後方参照を作成しますが、タグのない行とは一致しません。

http://www.regular-expressions.info/refadv.htmlから、オプションの演算子は後方参照に影響しないことがわかりました。

丸かっこは、それらの間の正規表現をグループ化します。それらは、後方参照で再利用できる内部の正規表現に一致するテキストをキャプチャし、グループ化された正規表現全体に正規表現演算子を適用できるようにします。

しかし、何かを誤解しているに違いありません。

タグ部分をオプションにして、存在する場合に後方参照を作成するにはどうすればよいですか?

4

5 に答える 5

3

これは後方参照の問題ではありません。問題は、一致したテキストを読み込むだけで正規表現が満たされたこと.*です。オプションの終了タグを読むために読み続ける必要はありませんでした。本当に行末まで読んでいる場合の最も簡単な解決策は、$(ドル記号) を追加して、正規表現が行全体に一致するようにすることです。

編集

ところで、他のものと一致すると言ったので、正規表現を文字通りに取りませんでしたが、明確.*にするために、行全体を消費します。[^{]*タグが飲み込まれないようにするようなものが必要です。それはあなたにとって問題ではないと思います。

于 2010-06-09T18:49:03.700 に答える
2

.*他の人が説明したことに加えて、あなたは「怠惰な」ものを作りたいかもしれません:

^.*?(\{\w+\})?
于 2010-06-09T18:55:31.563 に答える
1

みんなありがとう。私は答え、貪欲でない修飾子、および行末一致の組み合わせを使用しました。これはトリックを行うように見えるため、正規表現は次のようになります。

^.*?(\{\w+\})?$ 

タグではない中括弧がここに表示される可能性があるため、一致の最初の部分に [^{]* を使用したくありませんでしたが、タグは常に行末に表示されます。

答えてくれてありがとう、それらはすべて役に立ちました。

于 2010-06-09T19:40:58.180 に答える
1

David Gladfelter が言ったように、実際の問題は、オプションにすると一致しないことです。ただし、彼が提案した修正は機能しません編集1:彼が編集したものを使用する必要があります(これは私がこれを書いているときに書かれました)。問題は、量指定子 ( *+?{n,m}) が貪欲であることです。それらは常に可能な限り一致します。したがって、 を記述^.*(\{\w+\})?すると、.*は常に行全体に一致します。これは、空の一致がオプションのグループを満たすためです。?また、貪欲ですが、最初の貪欲 (の.*) が優先されることに注意してください。そのオプションのグループを中括弧で囲むことだけが許可されている場合は、明示的に次のように言って問題を解決できます。^[^\{]*(\{\w+\})?. このように、最初のチャンクは最初の中かっこまでのすべてに一致し、(?貪欲であるため) 可能であれば中かっこで囲まれた単語に一致します。

多くの場合、これを解決する別の方法は、 : 、、、およびを追加して量指定子を遅延(または貪欲でない、最小など) にすることです。しかし、これはここでは役に立ちません: 代わりに、もしそうすると、怠惰な人は 0 文字に一致しようとして成功し、オプションのグループは一致しません。それでも、ここでは機能しませんが、ツールボックスの便利なツールです。 編集 1: また、C# では使用できますが、これらはすべての正規表現エンジンで使用できるわけではないことに注意してください。?*?+???{n,m}?^.*?(\{\w+\})?.*?

于 2010-06-09T19:02:13.190 に答える
0

タグだけに興味があり、残りの文字列は気にしない場合は、タグをこの正規表現と一致させるだけで、作業がずっと楽になります ( rubular.com を参照してください)。

\{(\w+)\}$

つまり{word}、文字列の末尾にあるものと一致させようとしています。そこにない場合は、残念ながら一致しません。?修飾子や消極的なものは必要ありませ.*ん。

C# では、RegexOptions.RightToLeftとにかく接尾辞を一致させようとしているため、 を使用することもできます。おそらく次のようになります。

string[] lines = {
  "The quick brown fox jumps over the lazy dog",
  "The quick brown fox jumps over the lazy dog {tag}",
  "The quick brown fox jumps over the {lazy} dog",
  "The quick brown fox jumps over the {lazy} {dog}",
};

Regex r = new Regex(@"\{(\w+)\}$", RegexOptions.RightToLeft);

foreach (string line in lines) {
  Console.WriteLine("[" + r.Match(line).Groups[1] + "]");
}

これは出力します ( ideone.com で見られるように):

[]
[tag]
[]
[dog]
于 2010-06-11T09:08:51.200 に答える