如何在前后获得5个字符?

时间:2011-08-11 16:54:30

标签: php regex

我需要得到

bbish name3 more

bbish name4 more

$p = '%<a\s+href="my-anchor-name3"\s*>(?:.*)</a>%im';
$s = 'some rubbish
<a href="my-anchor-name1">name</a>more rubbish
more rubbish<a href="my-anchor-name2">name2</a>more rubbish
more rubbish<a href="my-anchor-name3">name3</a>more rubbish
more rubbish<a href="my-anchor-name3">name4</a>more rubbish
more rubbish<a href="my-anchor-name5">name5</a>more rubbish';
$out = preg_match_all($p, $s, $matches, PREG_SET_ORDER);

我做错了什么?

4 个答案:

答案 0 :(得分:3)

  

我做错了什么?

你并没有指示PHP做你想做的事情,这是主要的缺陷。


问题


修复

试试这个:

<?php
$matches = Array();
$p = '%(.{0,5})<a\s+href="my-anchor-name3"\s*>(.*?)</a>(.{0,5})%imm';
$s = 'some rubbish
<a href="my-anchor-name1">name</a>more rubbish
more rubbish<a href="my-anchor-name2">name2</a>more rubbish
more rubbish<a href="my-anchor-name3">name3</a>more rubbish
more rubbish<a href="my-anchor-name3">name4</a>more rubbish
more rubbish<a href="my-anchor-name5">name5</a>more rubbish';
$out = preg_match_all($p, $s, $matches, PREG_SET_ORDER);
print_r($matches);
?>

输出:

Array
(
    [0] => Array
        (
            [0] => bbish<a href="my-anchor-name3">name3</a>more 
            [1] => bbish
            [2] => name3
            [3] => more 
        )

    [1] => Array
        (
            [0] => bbish<a href="my-anchor-name3">name4</a>more 
            [1] => bbish
            [2] => name4
            [3] => more 
        )

)

Live demo.


进一步的工作

您可能希望进一步限制在这些反向引用中可能被吃掉的字符。

如果你不想以你的方式限制你的href价值(你现在以相当混乱的方式做到这一点):

$p = '%(.{0,5})<a\s+href="my-anchor-name\d+"\s*>(.*?)</a>(.{0,5})%imm';

Like this.


*这里真正的答案是你不应该使用正则表达式来解析HTML,这是一个众所周知的事实。 Marc拥有您使用的解决方案。

答案 1 :(得分:2)

不要使用正则表达式。期。使用DOm函数在特定节点的位置之前/之后提取文本节点是微不足道的。

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

$xp = new DOMXPath($dom);

$res = $xp->query('//a[starts-with(@href, "my-anchor-name")]');
$out = array()
foreach($res as $a) {
    $previous = substr($a->previousSibling->nodeValue, -5);
    $next = substr($a->nextSibling->nodeValue, -5);
    $here = $a->nodeValue;

    $out[] = $previous . $here . $next;
}

答案 2 :(得分:0)

您并没有真正提供足够的数据来完成这项工作,但根据上面的示例数据,这应该可行:

$p = '/(.{5})<a\shref="my\-anchor\-(name[0-9]+)">.*</a>(.{5})/';
if (preg_match($p, $s, $matches, PREG_SET_ORDER)) {
  echo "Matches found.";
} else {
  echo "Matches not found.";
}

然后根据需要简单处理$matches数组中的所有搜索匹配。

答案 3 :(得分:-1)

你可以在正则表达式(.{5})之前添加和附加这样的内容。

因此:

$p = '%(.{5})<a\s+href="my-anchor-name3"\s*>(?:.*)</a>(.{5})%im';