我似乎无法在php中掌握正则表达式。具体来说,是组捕获部分。
我有一个看起来像这样的字符串
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="List">
<tr class='row_type_1'>
<td class="time">
3:45 pm
</td>
<td class="name">
Kira
</td>
</tr>
<tr class='row_type_2'>
<td class="time">
4:00 pm
</td>
<td class="name">
Near
</td>
</tr>
</table>
我希望我的数组看起来像这样
Array
(
[0] => Array
(
[0] => 3:45 pm
[1] => Kira
)
[1] => Array
(
[0] => 4:00 pm
[1] => Near
)
)
我想只使用preg_match,而不是爆炸,array_keys或循环。我花了一段时间才弄清楚我需要一个/ s来计算换行数。我真的很想看到模式和捕获语法。
编辑:模式只需要(row_type_1 | row_type_2)来捕获我想要数据的表中只有两种类型的行。例如,在row_type_3之后是row_type_3,然后是row_type_1之后,则会忽略row_type_3,并且该数组只会添加row_type_1中的数据,就像我在下面所做的那样。
Array
(
[0] => Array
(
[0] => 3:45 pm
[1] => Kira
)
[1] => Array
(
[0] => 4:00 pm
[1] => Near
)
[2] => Array
(
[0] => 5:00 pm
[1] => L
)
)
答案 0 :(得分:1)
我会使用XPath和DOM从HTML中检索信息。如果HTML或查询变得更复杂,使用正则表达式可能会变得混乱。 (正如你目前所见)。 DOM和XPath是这方面的标准。为什么不使用它?
想象一下这段代码示例:
// load the HTML into a DOM tree
$doc = new DOMDocument();
$doc->loadHtml($html);
// create XPath selector
$selector = new DOMXPath($doc);
// grab results
$result = array();
// select all tr that class starts with 'row_type_'
foreach($selector->query('//tr[starts-with(@class, "row_type_")]') as $tr) {
$record = array();
// select the value of the inner td nodes
foreach($selector->query('td[@class="time"]', $tr) as $td) {
$record[0]= trim($td->nodeValue);
}
foreach($selector->query('td[@class="name"]', $tr) as $td) {
$record[1]= trim($td->nodeValue);
}
$result []= $record;
}
var_dump($result);
答案 1 :(得分:0)
由于某些原因,您不应使用正则表达式解析html。最大的原因是难以解释格式不正确的HTML,并且可能会变得越来越慢。
我建议使用php DOM解析器或php HTML解析器。
答案 2 :(得分:0)
试试这个:
function extractData($str){
preg_match_all("~<tr class='row_type_\d'>\s*<td class=\"time\">(.*)</td>\s*<td class=\"name\">(.*)</td>\s*</tr>~Usim", $str, $match);
$dataset = array();
array_shift($match);
foreach($match as $rowIndex => $rows){
foreach ($rows as $index => $data) {
$dataset[$index][$rowIndex] = trim($data);
}
}
return $dataset;
}
$myData = extractData($str);
答案 3 :(得分:0)
地狱的道路就在这里:
$pattern = '`<tr .*?"time">\s++(.+?)\s++</td>.*?"name">\s++(.+?)\s++</td>`s';
preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);
foreach ($matches as &$match) {
array_shift($match);
}
?><pre><?php print_r($matches);