[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: preg_match и пробелы
Страницы: 1, 2
SnowWind
Привет друзья
Есть исходный текст
Вот кусок
<div class="sub-info">
<h2
class="model">
iPhone 4 </h2>


<h3
class="capacity color">


Пытаюсь забрать из этого только - iPhone 4

preg_match ('#(?<=<h2 class="model">)(?:[\s]*)[a-zA-Z]{6}[\s]{1}[0-7]{1}[a-z]*(?:[\s]*)(?=</h2>)#us', $html, $model);


Но в переменную получаю iPhone 4 вместе с пробелами, как этого написать правильно, не используя trim?
timonbandit
Не люблю регулярки((( я б хтмл c помощью simpleXml парсил))
alted
Для данного примера можно так:


$a = '<div class="sub-info">
<h2 class="model">
iPhone 4 </h2>


<h3 class="capacity color">'
;
preg_match('#<h2 class="model">\s{1,}(\w.+)\s{2,}.*</h2>#isU',$a,$b);
var_dump($b[1]); //string(8) "iPhone 4"
SnowWind
я не пойму почему в моём варианте не работает, я же явно указываю все пробелы НЕ сохранять, нет всё равно сохраняет в результат
Placido
В нулевую подмаску ($b[0]) входит вся регулярка, поэтому и сохраняет. Как подсказал alted, необходимо заключить нужную часть выражения в скобки и смотреть результат в первой подгруппе ($b[1]). Можно было бы заключить пробелы в утверждения, типа такого:
(?<=<h2 class="model">\s*), (?=\s*</h2>)
но ретроспективная проверка (?<=) должна быть фиксированной длины и не допускает квантификаторов ?+*, поэтому только первый вариант.
SnowWind
Цитата (Placido @ 29.09.2013 - 15:08)
В нулевую подмаску ($b[0]) входит вся регулярка, поэтому и сохраняет.

Так я и спрашиваю почему у меня сохраняет только 1 подгруппу, а других совпадений нет?
Нет совпадений БЕЗ пробелов
Placido
Потому что в выражении только одна подмаска - нулевая. Для того чтобы было больше подгрупп, должно быть больше круглых скобок. Номера подгруппам присваиваются по открывающим скобкам в регулярном выражении. Пример:
$str = 'Мама мыла 4 рамы';

preg_match('/.* \d .*/', $str, $out1)
//$out1[0] === 'Мама мыла 4 рамы'

preg_match('/(.*) \d .*/', $str, $out2)
//$out2[0] === 'Мама мыла 4 рамы'
//$out2[1] === 'Мама мыла'


preg_match('(/(.* (\d)) .*/', $str, $out3)
//$out3[0] === 'Мама мыла 4 рамы'
//$out3[1] === 'Мама мыла 4'
//$out3[2] === '4'
SnowWind
благодарю за пример, сразу стало понятно smile.gif
SnowWind
как выбрать все значения между тэгами <h1>, <h2>, <span class="value"> в одно выражение?

<?php $html = '<h2 class="model">
iPhone 5 </h2>


<h3 class="capacity color">
32GB White </h3>

</div>
</div>

<div class="field">
<span class="name">IMEI: </span>
<span class="value">12345678912345</span>
</div>
<div class="field">
<span class="name">Serial Number: </span>
<span class="value">QWERTYUIOPAS</span>
</div>
<div class="field">
<span class="name">Activated: </span>
<span class="value">Yes</span>
</div>
<div class="field">
<span class="name">Telephone Technical Support: </span>
<span class="value">Expired</span>
</div>
<div class="field">
<span class="name">Repairs & Service Coverage: </span>
<span class="value">Expired</span>
</div>
<div class="field">
<span class="name">Country Purchased: </span>
<span class="value">United States</span>
</div>
<div class="field">
<span class="name">SIM Lock: </span>
<span class="value">Locked</span>
</div>'
; ?>


Вот так выбираю всё между span, но как захватить h1 и h2 содержимое не понимаю.

preg_match_all ('#(?<=<span class="value">).*([\w]+[\s]*[\w]*).*(?=</span>)#', $html, $res);
Placido
Сейчас тебе скажут, что HTML регулярками парсить нельзя)))

Для парсинга html есть куча заточенных под это дело инструментов (подобные вопросы задавали уже 100500 раз - поиск в помощь). С другой стороны, если очень хочется поизвращаться, это можно сделать и с помощью регулярок - вот статья, вот соответствующий комментарий.
SnowWind
хтмл тут статичный не изменяемый пользователями не вижу смысла искать библиотеки, узнавать у хостера есть ли они у него и т.д, вопрос в том, можно ли написать в 1 выражение? Или в этом случае расписывать в 3?
Игорь_Vasinsky
Цитата
что HTML регулярками парсить нельзя)))


ахахах

_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
Placido
В одно выражение можно. Для этого есть знак альтернативы - |:
...(1 альтернатива)...|...(2 альтернатива)...|..(3 альтернатива)...
1-я альтернатива будет в подгруппе 1, 2-я - в подгруппе 2, 3-я - в подгруппе 3.
Если хочется все в найденное получить в одной подгруппе, то есть такой способ:
(?|...(1 альтернатива)...|...(2 альтернатива)...|..(3 альтернатива)...)
В этом случае все альтернативы будут в подгруппе 1
SnowWind
хм так я уже пробовал, результат 0
preg_match_all ('#(?<=(<h1>)|(<span class="value">))[a-zA-Z0-9]+[\s]*[\w]*(?=(</span>)|(</h2))#ius', $html, $description);

не фарцает )
Placido
Держи, которое "фарцает".
preg_match_all ('#
(?<=<h1>) [a-zA-Z0-9]+[\s]*[\w]* (?=</h1)
| (?<=<h2>) [a-zA-Z0-9]+[\s]*[\w]* (?=</h2)
| (?<=<span[ ]class="value">) [a-zA-Z0-9]+[\s]*[\w]* (?=</span>)
#iusx'
, $html, $description);
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.