【问题标题】:How to parse a string without losing plus sign in PHP?如何在不丢失 PHP 中的加号的情况下解析字符串?
【发布时间】:2016-11-28 17:23:21
【问题描述】:

我正在解析 HTML 字符串以获取 PHP 中的值并将它们写入数据库。这是一个示例字符串:

<b>Adress:</b> 22 Examplary road, Nowhere <br>
<b>Phone:</b>  +371 12345678, +371 23456789<br>
<b>E-mail: </b>info@example.com<br>

字符串可以以随机方式格式化。它可以包含我没有解析的其他键,并且它可以包含重复的键。它也可以只包含我感兴趣的一些键或完全为空的。 HTML 也可能被破坏(示例标签:&lt;br)。我决定遵守规则,条目以\n 分隔,格式为key: value + 一些HTML。

首先,我使用这段代码使字符串可解析:

$parse = strip_tags($string);
$parse = str_replace(':', '=', $parse);
$parse = str_replace("\n", '&', $parse);
$parse = str_replace("\r", '', $parse);
$parse = str_replace("\t", '', $parse);

我的字符串现在看起来像这样:

Adress= 22 Examplary road, Nowhere&Phone=  +123 12345678, +123 23456789&E-mail= info@example.com

然后我使用parse_str() 获取值,然后在找到所需键时取出值:

        parse_str($parse, $values);

        $address = null;
        if (isset($values['Adress']))
            $address = trim($values['Adress']);

        $phone = null;
        if (isset($values['Phone']))
            $phone = trim($values['Phone']);

问题是我最终得到$phone = '371 12345678, 371 23456789' - 我失去了+ 标志。如何保存?

另外,如果您对如何改进此程序有任何提示,我很高兴知道这一点。有些条目有Website: example.com,其他有Web Site example.com...我很确定自动解析所有信息是不可能的,但我正在寻找可能的最佳解决方案。

解决方案

使用WEBjuju提供的技巧我现在正在使用这个:

preg_match_all('/([^:]*):\s?(.*)\n/Usi', $string, $matches, PREG_SET_ORDER);

$values = [];
foreach ($matches as $match)
{
    $key = strip_tags($match[1]);
    $key = trim($key);
    $key = mb_strtolower($key);
    $key = str_replace("\s", '', $key);
    $key = str_replace('-', '', $key);

    $value = strip_tags($match[2]);
    $value = trim($value);

    $descriptionValues[$key] = $value;
}

这让我可以从这个输入中走出来:

<b>Venue:</b> The Hall<br
<b>Adress:</b> 22 Examplary road, Nowhere <br>
<b>Phone:</b>  +371 12345678<br>
<b>E-mail: </b>info@hkliepaja.lv<br>
<b>Website:</b> <a href="http://example.com/" target="_blank">example.com</a><br>

到一个漂亮的 PHP 数组,具有同质化且希望可识别的键:

[
    'venue' => 'The Hall',
    'adress' => '22 Examplary road, Nowhere',
    'phone' => '+371 12345678',
    'email' => 'info@example.com',
    'website' => 'example.com',
];

它仍然没有考虑到缺少冒号的情况,但我认为我无法解决这个问题......

【问题讨论】:

  • @Andy Lester,我不确定我是否同意您重新标记...
  • 我读到html-parsing标签是从HTML代码中提取数据的描述,所以我添加了标签(似乎适合实际情况)。如果那是为网站解析之类的东西保留的,那么没有标签我就没有问题。
  • 我删除了它,因为 OP 实际上并没有解析任何 HTML。如果你愿意,可以把它放回去。
  • 哦,我明白了! OP 正在尝试抓取数据。这里的方法不是使用正则表达式,而是期望 html 以某种方式匹配,使得一系列 str_replaces 产生类似于 key-var encoded_string 的东西!我将开始一个新的解决方案,而不是将所有这些 cmets 留在误解 OP 实际尝试做的解决方案上。

标签: php parsing html-parsing


【解决方案1】:

意识到你有预制的 HTML符合简单的标准结构我可以告诉你,正则表达式匹配将是获取这些数据的最佳方式。这是一个让您上路的示例 - 我相信它并不能解决所有问题,但它解决了您在这篇文章中遇到的问题,即您在“查找键/var 匹配项”时遇到问题。

// now go get those matches!
preg_match_all('/<b>([^:]*):\s?<\/b>(.*)<br>/Usi', $string, $matches, PREG_SET_ORDER);
die('<pre>'.print_r($matches,true));

例如,这将输出如下内容:

Array
(
  [0] => Array
    (
        [0] => <b>Adress:</b> 22 Examplary road, Nowhere <br>
        [1] => Adress
        [2] =>  22 Examplary road, Nowhere
    )

  [1] => Array
    (
        [0] => <b>Phone:</b>  +371 12345678, +371 23456789<br>
        [1] => Phone
        [2] =>   +371 12345678, +371 23456789
    )

  [2] => Array
    (
        [0] => <b>E-mail: </b>info@example.com<br>
        [1] => E-mail
        [2] => info@example.com
    )

从那里开始,我猜你可以把它推入标准杆。

【讨论】:

  • 谢谢,这更接近我的需要。我会尝试使用/([^:]*):\s?(.*)\n/Usi,因为那里的 HTML 有时不符合结构。在这个数据集中,我最信任换行符和冒号。
【解决方案2】:

在将值放入字符串之前使用base64_encode()。在您收到此字符串的代码中,使用base64_decode() 将其取回。

page1.php

$string = '&Adress='.base64_encode('22 Examplary road, Nowhere').'&Phone='.base64_encode('+123 12345678, +123 23456789').'&Email='.base64_encode('info@example.com');
// string is sent via curl or some other transport to page2.php

page2.php

parse_str($string);
echo base64_decode($Adress); // 22 Examplary road, Nowhere
echo base64_decode($Phone); // +123 12345678, +123 23456789
echo base64_decode($Email); // info@example.com

【讨论】:

  • 您的回答基本上是评论。为什么不提供一些代码?
  • 你的意思是我应该在构造初始字符串时对其进行编码吗?如果是这样,那是不可能的 - 这些字符串是遗留数据,不是我创建的。
  • 我的意思是你说“我的字符串现在看起来像这样:”然后你打印应该是 urlencoded 数据的键值对......但你的数据不是 url 编码的。即使是这样,你最好使用 base64 编码。
  • 但是这些编码让我无法解析它。 urlencodebase64_encode 都对 &amp;= 进行编码,这是将字符串解析为 key =&gt; value 数组所需的...
  • @juris 只对值进行编码----&amp;key=".base64_encode($value)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-11
  • 1970-01-01
  • 2017-05-29
  • 2019-05-03
  • 2013-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多