5

*注:Array()の出力はPHP print_r()*です。

私はこのHTMLタグを持っています:

<tr>
    <td width="40" align="left"><div class="icSkill" id="skill4"></div></td>
    <td colspan="2">SOME_VALUE_I_WANT&nbsp;</td>
</tr>

私は本当にこれを正規表現で抽出したいのですが、この場合はHTMLパーサーを使用したくありません。

私はこの正規表現を実行します(ファイルの改行を無視するためにsフラグを使用します):

\<tr\>\<td\swidth="40"\salign="left"\>\<div\s+class="icSkill"\s+id="skill(\d+)".*\<\/tr\>

ここでの問題は、正規表現が最初に見つかった近くのTRタグで停止しないことですが、私はそれを望んでいます。私はそれがおそらくアサーションと関係があることを知っています、私だけが方法を知りません。

Array
(
    [0] => <tr><td width="40" align="left"><div class="icSkill" id="skill4"></div></td><td colspan="2">SOME_VALUE_I_WANT&nbsp;
</td></tr><tr><td rowspan="2" align="left"><div class="icGuard" id="guard9"></div></td></tr>
    [1] => 4
)

この場合、/ [^ <]*/のような基本的な例は機能しません。正規表現に次のようなことを伝える方法もありますか?

/[^A_STRING]*/ (in words; stop unless you find A_STRING)
OR BETTER EXAMPLE:
/[^A_STRING_FIRST_TIME]*/ (in words; stop unless you find A_STRING for the FIRST_TIME)
4

2 に答える 2

9

問題は貪欲です。.*できるだけ多くを消費します。あなたはそれを追加することによって貪欲にしないことができます?

~<tr><td\s+width="40"\s+align="left"><div\s+class="icSkill"\s+id="skill(\d+)".*?</tr>~s

また、ご覧のとおり、それほど多くのエスケープを行う必要はありません。読みやすさを妨げるだけです。

繰り返しを貪欲にしない別の方法は、修飾子を使用することですU。これにより、パターン全体ですべての繰り返しが全体的に貪欲になりません。ただし、ローカルバリアント(を使用)の方が好き?です。

いずれにせよ、模倣する別の可能性があります(これは、、、、、、、、、またはを含まない文字列と一致するため、機能し[^A_STRING]*ません)。繰り返しのすべての位置での先読みを使用できます。A_STRING

(?:(?!A_STRING).)*

.*(またはの代わりにこれを使用して.*?ください)。ほとんどの場合同等ですが、実行時間は異なる場合があります。さらに、解読するのは少し難しいです。

于 2012-12-12T14:48:29.233 に答える
1

これは難しいものです。通常、そこにはクラス識別子があり、簡単になります。

したがって、私があなたが何を望んでいるのかを理解していることを確認しましょう<td>。テーブルの行を閉じる直前に、最後のタグ内にあるものをすべてキャプチャする必要があります。その場合、ネガティブな先読みが必要です。

<td(?!.*?<td).*?>(.*?)<\/td>

これは、修飾子とともに、テーブル行の最後の要素にある場合sにキャプチャします。SOME_VALUE_I_WANT&nbsp;<td>

この正規表現で単純ではない唯一の要素は、負の先読み演算子です。これは、別のそのような要素が後に続かない要素<td(?!.*?<td)のみをキャプチャします。<td>

また、スター演算子を使用する場合は、通常、次のように貪欲でないように変更する必要があります(.*?)。これは、最初の試合で停止することを意味します。

于 2012-12-12T15:34:37.823 に答える