1

我正在研究从 zbozi.cz 获取数据的数据解析器,但我遇到了问题。函数 parse 正在准备我从 zbozi.cz 获得的数据到有效的 JSON 并对其进行解码。查看https://github.com/Northys/Venom/blob/master/libs/Venom/Strings.php

我不熟悉正则表达式,但我试图用我的书创建一个 - 我有这样的东西(我把它做空了):

/* <![CDATA[ */ new Zbozi.Common.Result( { id: 'itemRow-0', ... }, { itemId: '3118517',...}, { url: ... }, null ); /* ]]> */

而且我需要获得一个有效的 JSON 来使用我的解析函数对其进行解码。我正在使用模式/.*\( /preg_replace功能在出现之前删除东西{ id:...}。不幸的是,将来他们可以添加更多的空格,整理代码或使我的脚本不起作用的东西。

我需要做的就是编辑解析函数(链接如下)。第 23 行的正则表达式模式和str_replace以下行中的一些需要更改preg_replace功能。你能帮我么?

这是我的脚本使用的代码 - https://github.com/Northys/Venom/blob/master/crawled/1.html - 只需坚持 CTRL F 并找到Zbozi.Common.Result

而且我的脚本不适用于 https://github.com/Northys/Venom/blob/master/crawled/0.html - 第 305 行

我需要更改正则表达式以使其适用于这两个文件。

4

1 回答 1

1

你可以试试这个:

$subject = <<<'LOD'
/* <![CDATA[ */ new Zbozi.Common.Result( 
{ id: 'itemRow-0', url: 'http://www.muzikant.cz/zbozi/allen-heath-xone-22-81095.php', pos: '1' },
{ itemId: '3118517', longItemId: '117890214602569005', productId: '0', premiseId: '1675', zboziUserId: 'f11b5249-5e43-47f7-aca0-96ec4d0fde14',
  sessionId: 'kQ8Fq1bSww4nr9E1kPBc', q: 'Allen &amp; Heath Xone:22', title: 'ALLEN HEATH XONE:22', paid: 1, cn: '7770.00', frel: '948571',
  crel: '0.952682', irel: '0.960918', x: 'pict' },
{ url: '/action/1675/clickthru?c=aaFoxUbWdnjpMksl5JN9avgl-1p673W9H8qxBpkl0O4xUptIPy0Y8P_IA72jS2Se_vxNj-eGQ5McH7EUlfXeeDVCYNIunim45PB8RS-eizcZorpKyMNlwTnUdUb1PjkvFQXDbSjMJeJmRcGnSWOyQyAGcL5ZQcreNFnXv1Xr5yEDjNxbPjyiD1mZI1Vm3PuqU7XrSrhtPx_LdipcNNdk2skaKYqFH-vRreCOwZ3F7ZWFbeOByzi3bg8eVJsFmyqNBy0uKaSdAF_yGMym4ZujVZPzvExObpsAMSHb0CtLK5KhNNYgTXP6bRKDAeJLGc-nnMdNKlOMuBKZKFaJrrWo6M60zsCM4tHvFGb30gb3s_M=',
 label: 'item_featured', productName: 'ALLEN HEATH XONE:22', cp: '5B9DN0UD-qzuhuuvvKKZjg==' }, null ); /* ]]> */
LOD;

$replacements = array(
    '~/\* \s*+ \Q<![CDATA[\E \s*+ \*/ \s*+ new \s++ \QZbozi.Common.Result\E \s*+ \( \s*+~x' => '[',
    '~(?<=}) \s*+ , \s*+ null \s*+ \); \s*+ /\* \s*+ ]]> \s*+ \*/~x'                        => ']',
    '~(?> \\{2} )*+ \K \'~x'                                                                => '"',
    '~" [^"]*+ " (*SKIP) (*FAIL) | \s*+ (\w++) \s*+ : \s*+~x'                               => ' "$1":'
);

foreach ($replacements as $pattern => $replacement) {
    $subject = preg_replace($pattern, $replacement, $subject);
}

var_dump($subject);

图案细节:

 前两种模式旨在修剪(未来)JSON 对象前后不需要的内容。最后两个模式用于引号。

在所有模式中:

为了提高可读性,我使用了x修饰符(扩展 mod),因此忽略了空格。同样,\Q.....\E语法用于编写文字子串。(内部忽略特殊字符)。

所有量词都是所有格(++*+)而不是简单的量词(+*)。获得结果不是必需的(除了在第三种模式中),但那些向正则表达式引擎表明不需要记录回溯位置。您可以在此处找到更多相关信息。替换非捕获基团
原子团也是如此 (?>.....)(?:.....)

第一种模式:

没什么特别的,必须转义文字 atserisk 并\Q...\E使用语法并避免转义方括号和点。

第二种模式:

后视 用于检查之前是否有右(?<=})大括号。(这只是一个检查,这意味着里面的子(?<=...)模式不是匹配的一部分)

第三种模式:

此模式将找到未转义的单引号。为此,您必须验证单引号前是否有偶数个反斜杠或没有反斜杠。实际上,\\\\'是两个反斜杠和一个引号,\\\\\'是两个反斜杠和一个转义引号(即文字引号)。

\K将从匹配结果中删除模式的开头(反斜杠检查)。只剩下单引号。

第四种模式:

这将找到所有后跟冒号的不在双引号内的单词(如http:

您必须先找到双引号内的所有内容,"[^"]*+"然后才能将其从匹配结果中排除。
要做到这一点,你不能使用这个\K技巧,因为你是一个交替的一部分:.......\K|.......(如果第一部分成功,该preg_replace()函数将在双引号内的每个子字符串之后添加替换模式!
唯一的方法是正则表达式引擎在双引号中处理这些内容并失败。要做到这一点,您可以使用这两个回溯控制动词:(*SKIP)(*FAIL)
(*SKIP)向正则表达式引擎指示先例子模式将失败并且可以跳过。
(*FAIL)迫使模式失败。

这样,您就避免了双引号内的所有内容。然后交替的另一部分将只找到双引号外带有冒号的单词。

于 2013-10-25T23:55:57.640 回答