5

私が尋ねた前の質問に続いて:

正規表現を使用して、2 つの文字列の間にあるテキストを一致させるにはどうすればよいですか。これらの 2 つの文字列自体が他の 2 つの文字列で囲まれ、内側と外側の囲み文字列の間に任意の量のテキストがありますか?

私はこの答えを得ました:

/outer-start.*?inner-start(.*?)inner-end.*?outer-end/

外側の囲み文字列と内側の囲み文字列の間のテキストから特定の文字列を除外する方法を知りたいと思います。

たとえば、次のテキストがあるとします。

アウタースタートいくつかのテキストインナースタート 欲しいテキスト インナーエンドもう少しテキストアウターエンド

'some text' と 'some more text' に 'unwanted' という単語を含めないようにしたいと思います。

つまり、これで問題ありません。

外側の開始いくつかの必要なテキスト内側の開始 テキスト-その-私が欲しい 内側の終了いくつかのより必要なテキスト外側の終了

しかし、これはOKではありません:

外側から不要なテキストを開始する内側から開始 したいテキストを 内側から終了する 不要なテキストを外側から終了する

または、さらに説明すると、上記の前の回答の外側と内側の区切り文字の間の表現では、「不要」という単語を除外する必要があります。

これは正規表現を使用して一致させるのは簡単ですか?

4

6 に答える 6

6

最初と最後 (真ん中は除く).*?を に置き換え(?:(?!unwanted).)*?ます。((?:...)は非キャプチャ グループで、(?!...)は否定的な先読みです。)

ただし、これはすぐに、実際の(例ではなく)使用におけるコーナーケースと警告で終わります。また、実際に何をしているのかを尋ねると(たとえそれらが単純化されていても、実際の例では、作成された例ではなく) )、より適切な回答が得られる可能性があります。

于 2010-01-02T23:03:25.783 に答える
2

「正規表現でこれを行うにはどうすればよいか」よりも、自問するほうがよい質問です。「この問題を解決するにはどうすればよいですか?」です。言い換えれば、正規表現を使って大きな問題を解決しようとすることに夢中にならないでください。問題の半分を正規表現で解決できる場合は、そうしてから、残りの半分を別の正規表現またはその他の手法で解決してください。

たとえば、不要なテキストを無視して、すべての一致を取得するデータをパスします (読み取り: 不要なテキストがある場合とない場合の両方の結果を取得します)。次に、削減されたデータ セットをパスし、不要なテキストを含む結果を除外します。この種のソリューションは、記述しやすく、理解しやすく、長期にわたって保守しやすいものです。そして、このアプローチで解決する必要がある可能性が高い問題については、十分に高速です。

于 2010-01-02T23:33:40.230 に答える
1

.*?あなたはと置き換えることができます

 ([^u]|u[^n]|un[^w]|unw[^a]|unwa[^n]|unwan[^t]|unwant[^e]|unwante[^d])*?

これは「純粋な」正規表現のソリューションです。使用している言語では、より洗練された構造を使用できる場合があります。

于 2010-01-02T23:02:02.463 に答える
1

単純な正規表現では簡単に行うことはできませんが、Perl などの一部のシステムには、それを容易にする拡張機能があります。1 つの方法は、否定先読みアサーションを使用することです。

/outer-start(?:u(?!nwanted)|[^u])*?inner-start(.*?)inner-end.*?outer-end/

重要なのは、「不要」を (「u」の後に「nwanted」が続かない) または (「u」ではない) に分割することです。これにより、パターンを進めることができますが、すべての「不要な」文字列を見つけて拒否します。

ただし、これを多く行うと、人々はあなたのコードを嫌うようになる可能性があります。;)

于 2010-01-02T23:05:52.573 に答える
-1

最後の .* を置き換えてみてください。with: (?!(.*不要なテキスト.*))

うまくいきましたか?

于 2010-01-02T23:01:35.900 に答える