4

これがどのように機能するか説明できますか?次に例を示します。

<!-- The quick brown fox 
              jumps over the lazy dog -->

<!--[if IE 7]>
    <link rel="stylesheet" type="text/css" href="/supersheet.css" />
<![endif]-->

<!-- Pack my box with five dozen liquor jugs -->

まず、次の正規表現を使用して、条件付きコメント内のコンテンツを一致させようとしました。

/<!--.*?stylesheet.*?-->/s

正規表現が最初<!--と最後の の前のすべてのコンテンツに一致するため、失敗しました-->。次に、先読みアサーションで別のパターンを使用してみました。

/<!--(?=.*?stylesheet).*?-->/s

それは機能し、私が必要とするものと正確に一致します。ただし、次の正規表現も機能します。

/<!--(?=.*stylesheet).*?-->/s

最後の正規表現には、先読みアサーションに消極的な量指定子がありません。そして今、私は混乱しています。誰がそれがどのように機能するか説明できますか? この例にはもっと良い解決策があるのではないでしょうか?

更新しました:

別のドキュメントで先読みアサーションを使用して正規表現を使用しようとしましたが、コメント間のコンテンツを一致させることができませんでした。したがって、これ/<!--(?=.*?stylesheet).*?-->/s(およびこれ/<!--(?=.*stylesheet).*?-->/s) は正しくありません。それを使用せず、他の提案を試してください。

更新しました:

解決策はJonny 5によって発見されました(回答を参照)。彼は次の 3 つのオプションを提案しました。

  1. 否定されたハイフンを使用して一致を制限します。このオプションは、タグ間にハイフンがない場合にのみ機能します。スタイルシートに URL がある場合/style-sheet.css、それは機能しません。
  2. エスケープ シーケンスの使用: \K. それは魅力のように機能します。欠点は次のとおりです。
    • それは非常に遅いです(私の場合、他のソリューションよりも8〜10倍遅かったです)
    • PHP 5.2.4 以降でのみ利用可能
  3. 先読みを使用して一致を絞り込みます。これは私が達成しようとした目標ですが、ルックアラウンド アサーションを使用した私の経験では、タスクを実行するには不十分でした。

私の例では、次のことが良い解決策だと思います。

/(?s)<!--(?:(?!<!).)+?stylesheet.+?-->/

同じですがs、最後に修飾子があります:

/<!--(?:(?!<!).)+?stylesheet.+?-->/s

私が言ったように、これは良い解決策ですが、私はなんとかパターンを改善し、私の場合はより速く動作する別のものを見つけました.

したがって、最終的な解決策は次のとおりです。

/<!--(?:(?!-->).)+?stylesheet.+?-->/s

参加者の皆様、興味深い回答をありがとうございました。

4

2 に答える 2

2

部分だけを一致させるには<!--... stylesheet...-->方法はたくさんあります。

1.)否定されたハイフンを使用し[^-] て一致を制限し、その間にとどまり<!--ますstylesheet

(?s)<!--[^-]+stylesheet.+?-->

[^-]ハイフン以外の文字のみを許可します。regex101 のテストを参照してください。


2.) 正規表現の労力をあまりかけずに「最後」または最も近い一致を取得するには、貪欲な ドットを前に置いて食べ尽くすこともできます。グローバルに一致しない場合、または一致するアイテムが 1 つだけの場合は理にかなっています。\K を使用して、貪欲の後にリセットします。

(?s)^.*\K<!--.+?stylesheet.+?-->

regex101 のテストを参照してください。キャプチャ グループを使用して $1 を取得することもできます。 (?s)^.*(<!--.+?stylesheet.+?-->)


3.)先読みを使用して絞り込むと、通常はよりコストがかかります。

(?s)<!--(?:(?!<!).)+?stylesheet.+?-->

regex101 のテストを参照してください。(?!<!).間の各文字を先読みし、別の文字を開始<!--stylesheetない場合は<!... 1 つの要素内にとどまります。否定されたハイフン ソリューションに似ています。


1つ以上.*に使用.+する代わりに、何を一致させるかによって異なります。こちらの方が合います。 使用するソリューションは、正確な要件によって異なります。この場合、最初のものを使用します。+

于 2015-08-16T08:01:01.840 に答える