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


Extracting multiple values from variable and assigning new variables

我在一个变量($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

有人能给我指正确的方向吗。

我谦虚地建议使用HTML解析器,尤其是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
";

对于记录,preg_match返回:

如果模式匹配给定主题,则为1;如果不匹配,则为0;如果出现错误,则为FALSE。

这就是为什么每个变量中都有1。

正确的代码应该是

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

尽管如果您正在解析整个HTML文档,但HTML解析器绝对是最好的选择。

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

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

预匹配手动

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

这样就可以了。

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()您的结果。

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

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

查看此处:http://en.wikipedia.org/wiki/Dyck_language

你需要检查匹配的括号——不是一个有限状态机——它是一个Pushdown自动机(好吧,regex可能会工作,不管: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;
    }