PHP preg_match_all正则表达式只提取字符串中的数字

时间:2012-03-14 15:57:12

标签: php regex preg-match-all

我似乎无法找出用于从字符串中提取特定数字的正确正则表达式。我有一个HTML字符串,其中包含各种img标记。 HTML中有一堆img标签,我想从中提取一部分值。他们遵循以下格式:

<img src="http://domain.com/images/59.jpg" class="something" />
<img src="http://domain.com/images/549.jpg" class="something" />
<img src="http://domain.com/images/1249.jpg" class="something" />
<img src="http://domain.com/images/6.jpg" class="something" />

因此,在“通常”为.jpg之前的数字长度不同(可能是.gif,.png或其他东西)。我只想从该字符串中提取数字。

第二部分是我想使用该数字在数据库中查找条目并获取该特定图像ID的alt / title标签。最后,我想将返回的数据库值添加到字符串中并将其重新放回HTML字符串中。

关于如何处理它的任何想法都会很棒......

到目前为止,我已经尝试过:

$pattern = '/img src="http://domain.com/images/[0-9]+\/.jpg';
preg_match_all($pattern, $body, $matches);
var_dump($matches);

7 个答案:

答案 0 :(得分:2)

我认为这是最好的方法:

  1. 使用HTML解析器提取图像标记
  2. 使用正则表达式(或可能是字符串操作)来提取ID
  3. 查询数据
  4. 使用HTML解析器插入返回的数据
  5. 这是一个例子。我可以想到一些改进,例如使用字符串操作而不是正则表达式。

    $html = '<img src="http://domain.com/images/59.jpg" class="something" />
    <img src="http://domain.com/images/549.jpg" class="something" />
    <img src="http://domain.com/images/1249.jpg" class="something" />
    <img src="http://domain.com/images/6.jpg" class="something" />';
    $doc = new DOMDocument;
    $doc->loadHtml( $html);
    
    foreach( $doc->getElementsByTagName('img') as $img)
    {
        $src = $img->getAttribute('src');
        preg_match( '#/images/([0-9]+)\.#i', $src, $matches);
        $id = $matches[1];
        echo 'Fetching info for image ID ' . $id . "\n";
    
        // Query stuff here
        $result = 'Got this from the DB';
    
        $img->setAttribute( 'title', $result);
        $img->setAttribute( 'alt', $result);
    }
    
    $newHTML = $doc->saveHtml();
    

答案 1 :(得分:1)

使用正则表达式,您可以非常轻松地获取数字。 preg_match_all的第三个参数是一个引用数组,它将填充找到的匹配项。

preg_match_all('/<img src="http:\/\/domain.com\/images\/(\d+)\.[a-zA-Z]+"/', $html, $matches);
print_r($matches);

这将包含它找到的所有内容。

答案 2 :(得分:1)

使用preg_match_all

preg_match_all('#<img.*?/(\d+)\.#', $str, $m);
print_r($m);

<强>输出:

Array
(
    [0] => Array
        (
            [0] => <img src="http://domain.com/images/59.
            [1] => <img src="http://domain.com/images/549.
            [2] => <img src="http://domain.com/images/1249.
            [3] => <img src="http://domain.com/images/6.
        )

    [1] => Array
        (
            [0] => 59
            [1] => 549
            [2] => 1249
            [3] => 6
        )

)

答案 3 :(得分:1)

考虑使用preg_replace_callback

使用此正则表达式:(images/([0-9]+)[^"]+")

然后,作为callback参数,使用匿名函数。结果:

$output = preg_replace_callback(
    "(images/([0-9]+)[^\"]+\")",
    function($m) {
        // $m[1] is the number.
        $t = getTitleFromDatabase($m[1]); // do whatever you have to do to get the title
        return $m[0]." title=\"".$t."\"";
    },
    $input
);

答案 4 :(得分:0)

此正则表达式应与数字部分匹配:

\/images\/(?P<digits>[0-9]+)\.[a-z]+

您的$matches['digits']应该包含您想要的所有数字作为数组。

答案 5 :(得分:0)

$matches = array();
preg_match_all('/[:digits:]+/', $htmlString, $matches);

然后遍历matches数组以重建HTML并在数据库中查找。

答案 6 :(得分:0)

在解析糟糕的HTML时,单独的正则表达式有点令人失望。 DOMDocument的HTML处理非常适合提供热门和新鲜的标签,xpath用于选择图像srcs和一个简单的sscanf来提取数字:

$ids = array();
$doc = new DOMDocument();
$doc->loadHTML($html);
foreach(simplexml_import_dom($doc)->xpath('//img/@src[contains(., "/images/")]') as $src) {
    if (sscanf($src, '%*[^0-9]%d', $number)) {
        $ids[] = $number;
    }
}

因为它只给你一个数组,为什么不封装它呢?

$html = '<img src="http://domain.com/images/59.jpg" class="something" />
<img src="http://domain.com/images/549.jpg" class="something" />
<img src="http://domain.com/images/1249.jpg" class="something" />
<img src="http://domain.com/images/6.jpg" class="something" />';

$imageNumbers = new ImageNumbers($html);

var_dump((array) $imageNumbers);

这给了你:

array(4) {
  [0]=>
  int(59)
  [1]=>
  int(549)
  [2]=>
  int(1249)
  [3]=>
  int(6)
}

通过上面的函数很好地包装成ArrayObject

class ImageNumbers extends ArrayObject
{
    public function __construct($html) {
        parent::__construct($this->extractFromHTML($html));
    }
    private function extractFromHTML($html) {
        $numbers = array();
        $doc = new DOMDocument();
        $preserve = libxml_use_internal_errors(TRUE);
        $doc->loadHTML($html);
        foreach(simplexml_import_dom($doc)->xpath('//img/@src[contains(., "/images/")]') as $src) {
            if (sscanf($src, '%*[^0-9]%d', $number)) {
                $numbers[] = $number;
            }
        }
        libxml_use_internal_errors($preserve);
        return $numbers;
    }
}

如果您的HTML格式不正确甚至DOMDocument::loadHTML()无法处理它,那么您只需要在ImageNumbers类内部处理它。