htmlのoptionを否定先読みで加工


今までなんとなく使ってた否定先読みが理解できた気がしたので整理

最近何故か、htmlのoptionを特定のvalue以外除去、という処理を依頼される
既にoptionがハードコードされた状態からの処理になるのでpreg_replaceで検討

例えば、以下のようなoptionについて、いくつかのパターンを見ていく

$subject = <<<OPTION
<option value="111">111</option>
<option value="222">222</option>
<option value="333">333</option>
<option value="444">444</option>
<option value="555">555</option>
<option value="11111">11111</option>
<option value="22222">22222</option>
<option value="33333">33333</option>
<option value="44444">44444</option>
<option value="55555">55555</option>

OPTION;

555だけを残すパターン

$pattern = '/<option (?!value="555")value="\d*">.*<\/option>\n/';
preg_replace($pattern ,'',$subject);
↓↓↓
<option value="555">555</option>

<option (?!value="555")の部分は
(?!value="555")<optionの直後の位置であり、
<optionの後にvalue="555"が後に続かない
ものとなる

5を含むものだけを残すパターン

$pattern = '/<option (?!value="\d*5\d*")value="\d*">.*<\/option>\n/';
preg_replace($pattern ,'',$subject);
↓↓↓
<option value="555">555</option>
<option value="55555">55555</option>

1,3,5を含むものだけを残すパターン

$pattern = '/<option (?!value="\d*[135]\d*")value="\d*">.*<\/option>\n/';
preg_replace($pattern ,'',$subject);
↓↓↓
<option value="111">111</option>
<option value="333">333</option>
<option value="555">555</option>
<option value="11111">11111</option>
<option value="33333">33333</option>
<option value="55555">55555</option>

5桁の数字だけを残すパターン

$pattern = '/<option (?!value="\d{5,5}")value="\d*">.*<\/option>\n/';
preg_replace($pattern ,'',$subject);
↓↓↓
<option value="11111">11111</option>
<option value="22222">22222</option>
<option value="33333">33333</option>
<option value="44444">44444</option>
<option value="55555">55555</option>