我正在研究从zbozi.cz获取数据的数据解析器,我遇到了问题。 函数解析正在准备从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:...}
出现之前删除内容。不幸的是,将来他们可以添加更多的空格,整理代码或使我的脚本不起作用的东西。
我需要的一切就是编辑解析功能(链接下面的链接)。对于str_replace
函数,需要更改第23行上的正则表达式模式和以下行中的某些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行
我需要更改正则表达式以使其适用于这两个文件。
答案 0 :(得分: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 & 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);
这两个第一个模式旨在修剪(futur)JSON对象之后和之前不需要的内容。最后两种模式用于引用。
所有模式:
为了更具可读性,我使用x
修饰符(扩展mod),因此忽略了空格。以同样的方式,\Q.....\E
语法用于编写litteral子字符串。 (内部忽略特殊字符。)
所有量词都具有占有性(++
或*+
),而非简单量词(+
或*
)。获得结果并不是必需的(除了第三种模式),但那些表明正则表达式引擎不需要记录回溯位置。您可以找到有关此here的更多信息
替换非捕获组(?>.....)
(?:.....)
也是如此
第一种模式:
没有什么特别的,字面上的atserisk必须被转义并使用\Q...\E
语法,并避免摆脱方括号和圆点。
第二种模式:
lookbehind (?<=})
用于检查之前是否有结束花括号。 (这只是一个检查,这意味着(?<=...)
内的子模式不是匹配的一部分)。
第三种模式:
此模式将查找未转义的单引号。为此,您必须在单引号之前验证是否存在偶数个反斜杠或没有反斜杠。实际上,\\\\'
是两个反斜杠和一个引号,\\\\\'
是两个反斜杠和一个转义引号(即文字引号)。
\K
将从匹配结果中删除模式的开头(反斜杠检查)。仍然只有单引号。
第四种模式:
这将找到所有不在双引号(如http:
)内的冒号后面的单词。
您必须先找到双引号"[^"]*+"
内的所有内容才能将其从匹配结果中排除。
为此,您无法使用\K
技巧,因为您是交替的一部分:.......\K|.......
。 (如果第一部分成功,preg_replace()
函数将在双引号内的每个子字符串后添加替换模式!)
唯一的方法是正则表达式引擎以双引号继续这些内容并失败。要做到这一点,您可以使用这两个backtrack control verbs:(*SKIP)
和(*FAIL)
(*SKIP)
向正则表达式引擎指示先前的子模式将失败并且可以跳过
(*FAIL)
迫使模式失败。
这样你就避免了双引号内的所有内容。然后,交替的另一部分将只找到带双引号外的冒号的单词。