从变量中提取多个值并分配新变量

时间:2014-11-07 09:10:39

标签: php regex

我在一个变量($ product_info)中有一个完整的HTML页面,我试图将以下值转换为单独的变量

<h1 itemprop="name">Product name</h1>
<span id="prvat">£285.60</span>
<span id="spc">142020EB</span>

我正在尝试使用以下php代码,但它根本不输出预期结果

$product_info =
('
<h1 itemprop="name">Product name</h1>
<span id="prvat">£285.60</span>
<span id="spc">142020EB</span>
');

$product_name = preg_match('/<h1 itemprop="name">(.*)<\/h1>/', $product_info);
$price = preg_match('/<span id="prvat">(.*)<\/span>/', $product_info);
$product_code = preg_match('/<span id="spc">(.*)<\/span>/', $product_info);

echo ("Product Name = ".$product_name."<br>Price = ".$price."<br>Product Code = ".$product_code);

这是输出

Product Name = 1
Price = 1
Product Code = 1

请有人指出我正确的方向。

5 个答案:

答案 0 :(得分:4)

我谦虚地建议使用HTML Parser,特别是DOMDocument:

$product_info = '
<h1 itemprop="name">Product name</h1>
<span id="prvat">£285.60</span>
<span id="spc">142020EB</span>
';

$dom = new DOMDocument();
$dom->loadHTML($product_info);
$xpath = new DOMXpath($dom);

$product_name = $xpath->evaluate('string(//h1[@itemprop="name"]/text())');
$price = $xpath->evaluate('string(//span[@id="prvat"]/text())');
$product_code = $xpath->evaluate('string(//span[@id="spc"]/text())');

echo "
Product Name =  $product_name <br/>
Price =         $price <br/>
Product Code =  $product_code
";

答案 1 :(得分:1)

对于记录,preg_match返回:

  

1如果模式与给定主题匹配,则为0(如果不匹配),如果发生错误则为FALSE。

这就是你在每个变量中得到1的原因。

正确的代码是

preg_match('/<h1 itemprop="name">(.*)<\/h1>/', $product_info, $product_name);

虽然如果您正在解析整个HTML文档,HTML parser绝对是可行的方法。

答案 2 :(得分:1)

你离我很远。您只是没有给PHP var存储结果。$matches是存储结果的可选项。如果您不提供,preg_match将返回truefalse,具体取决于$string是否匹配。

preg_match ( string $pattern , string $subject, array $matches);

preg_match manual

  

如果提供了匹配,那么它将填充搜索结果。 $ matches [0]将包含与完整模式匹配的文本,$ matches 1将具有与第一个捕获的带括号的子模式匹配的文本,依此类推。

这应该这样做。

preg_match('/<h1 itemprop="name">(.*)<\/h1>/', $product_info, $product_name);
preg_match('/<span id="prvat">(.*)<\/span>/', $product_info, $price);
preg_match('/<span id="spc">(.*)<\/span>/', $product_info, $product_code);

然后只需print_r()您的搜索结果。

答案 3 :(得分:1)

preg_match有3个参数,第一个参数是正则表达式,第二个参数是字符串,最后一个存储所有cactched结果。

所以你应该使用:
if(preg_match('/<h1 itemprop="name">(.*)<\/h1>/', $product_info, $result) { $product_info = $result[1]; )

答案 4 :(得分:1)

看这里:http://en.wikipedia.org/wiki/Dyck_language

你需要检查匹配的括号而不是有限状态机它的下推自动机(正则表达式可能无论如何都可以工作:D),但只是为了显示处理这些类型语言的另一种方法:

C#:

static void Main(string[] args)
    {
        Console.ForegroundColor = ConsoleColor.Green;
        Stopwatch timer = new Stopwatch();
        timer.Start();
        VerweisKeller k = new VerweisKeller(); // This is just a german name for my own stack implementation use the .NET Stack<T> instead

        bool fail = false;
        string a = "[[[((())[[((([()])))[()()]([])]([([([])])])])]]][[[((())[[(([()]))[()()][((()))][][()()]()[][(())][][]([])]([([([])])])])]]]"; 
        char[] tape = a.ToCharArray();
        int countChars = 0;
        Console.WriteLine("{0} \n", a);

        for (int i = 0; i < tape.Length && !fail; ++i)
        {
            switch (tape[i])
            {
                case ('('):
                case ('['): 
                    k.push(tape[i]);
                    break;

                case (')'):
                    fail = !checkClosingBracketsRound(k);
                    break;

                case (']'):
                    fail = !checkClosingBracketsSquared(k);
                    break;

                default:
                    break;
            }++countChars;
        } 
        if (!fail && k.empty())
            Console.WriteLine("accepted");
        else 
            Console.WriteLine("not accepted");
        Console.WriteLine(countChars);
        timer.Stop();
        Console.WriteLine("Time: {0}", timer.Elapsed);
        Console.ReadKey();
    }

    private static bool checkClosingBracketsSquared(VerweisKeller k)
    {
        if (!k.empty() && ((char)k.top()) == '[')
        {
            k.pop();
            return true;
        }
        return false;
    }

    private static bool checkClosingBracketsRound(VerweisKeller k)
    {
        if (!k.empty() && ((char)k.top()) == '(')
        {
            k.pop();
            return true;
        }
        return false;
    }