准备正则表达式以使用格式良好的代码


Prepare regex to work with well-formated code

我正在研究从 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:...}出现之前删除内容。 不幸的是,将来他们可以添加更多的空格,整理代码或使我的脚本不起作用的东西。

我所需要的只是编辑解析函数(链接下方)。第 23 行上的正则表达式模式和以下行上的一些str_replace需要更改以preg_replace函数。你能帮帮我吗?

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

而且我的脚本无法使用https://github.com/Northys/Venom/blob/master/crawled/0.html - 305 路

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

你可以试试这个:

$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)强制模式失败。

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