2013-02-12 4 views
1

Я пытаюсь соответствовать этому (имя, в частности):Мое регулярное выражение не знает, когда остановиться

<tr> 
    <th class="name">Name:</th> 
    <td>John Smith</td> 
</tr> 

Как это:

preg_match('/<th class="name">Name:<\/th>.+?<td>(.+)<\/td>/s', $a, $b); 

Однако, в то время как он соответствует имя, оно не останавливается в конце имени. Он продолжает собирать еще 150 персонажей. Почему это? Я хочу только совместить имя.

+0

Использовать HTML-парсер, пожалуйста! Во всяком случае, исправить: '(. +)' -> '(. +?)' – nhahtdh

+0

@nhahtdh: Слишком поздно! –

+0

replace '(. +)' To '([^ <] +)' – vlcekmi3

ответ

3

Сделать последний квантор нежадным: preg_match('/<th class="name">Name:<\/th>.+?<td>(.+?)<\/td>/s', $a, $b);

+0

Спасибо, что сработали. –

0

Dont использовать регулярное выражение для разбора HTML, его очень легко с DOMDocument:

<?php 
$html = <<<HTML 
<tr> 
    <th class="name">Name:</th> 
    <td>John Smith</td> 
</tr> 
<tr> 
    <th class="name">Somthing:</th> 
    <td>Foobar</td> 
</tr> 
HTML; 

$dom = new DOMDocument(); 
@$dom->loadHTML($html); 

$ret = array(); 
foreach($dom->getElementsByTagName('tr') as $tr) { 
    $ret[trim($tr->getElementsByTagName('th')->item(0)->nodeValue,':')] = $tr->getElementsByTagName('td')->item(0)->nodeValue; 
} 

print_r($ret); 
/* 
Array 
(
    [Name] => John Smith 
    [Somthing] => Foobar 
) 
*/ 
?> 
0
preg_match('/<th class="name">Name:<\/th>\s*<td>(.+?)<\/td>/s', $line, $matches); 

Матч только пробельные между </th> и <td>, и не - ответный матч за имя.

0
preg_match('/<th class="name">Name:<\/th>.+?<td>(?P<name>.*)<\/td>/s', $str, $match); 

echo $match['name']; 
0

Вот ваш матч

preg_match(!<tr>\s*<th[^>]*>Name:</th>\s*<td>([^<]*)</td>\s*</tr>!s) 

он будет работать отлично.