@niko83

Регулярные выражения

есть текст вида:
<tr class="cls1">
<td>один</td>
<td>два</td>
<td>три</td>
</tr>
<tr class="cls2">
<td>четыре</td>
<td>пять</td>
</tr>


выражение вида:
preg_match_all('/<tr class="cls1">.*<td>(.*)<\/td>.*<\/tr>/Umis', $this->file, $match);
возвращает только первое включение <td> «один»
в то время как мне нужно извлечь все <td> из <tr class=«cls1»> «один», «два», «три»
  • Вопрос задан
  • 3706 просмотров
Пригласить эксперта
Ответы на вопрос 7
sajgak
@sajgak
Извините, точно не подскажу, но на нужное поведение влияет «жадность» алгоритма, которая устанавливается одним из флагов после регулярки. Поищите информацию по этому поводу.
Ответ написан
Комментировать
grcool
@grcool
Так вы и забираете одну ТДшку регуляркой.

preg_match('/<tr class="cls1">(.*)<\/tr>/Umis', $file, $match_temp);
preg_match_all('/<td>(.*)<\/td>/Umis', $match_temp[1], $match);
Ответ написан
@Jazzist
Добавьте квантификатор жадности /g
Ответ написан
Комментировать
frol
@frol
Линуксоид
С PHP регекспами не знаком, но вы в самом регекспе сказали искать только 1 td…
<tr class="cls1">.*?(?:<td>(.*?)<\/td>.*?)*<\/tr>

вот где-то так должно быть, но я не знаю как PHP отнесётся к конструкции .*? — если плохо отнесётся, то замените на просто .*
Ответ написан
Комментировать
vermilion1
@vermilion1
Не по делу: для валидности после <td>пять</td> еще ячейка нужна (<td></td>)
Ответ написан
Комментировать
patashnik
@patashnik
А что если воспользоваться DOM + Xpath?
Ответ написан
Комментировать
patashnik
@patashnik
Попробуйте так:
$regex = "~(?:(?<=cls1\">)|(?<=<\/td>)).<td>([^<]+)</td>(?=.*cls2)~is";

preg_match_all(regex, $this->file, $matches);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы